/// <summary> /// Get the states of all BIP 9 deployments listed in the <see cref="BIP9Deployments"/> enumeration. /// </summary> /// <param name="pindexPrev">The previous header of the block to determine the states for.</param> /// <returns>An array of <see cref="ThresholdState"/> objects.</returns> public ThresholdState[] GetStates(ChainedHeader pindexPrev) { ThresholdState[] array = new ThresholdState[this.consensus.BIP9Deployments.Length]; for (int i = 0; i < array.Length; i++) { array[i] = this.GetState(pindexPrev, i); } return(array); }
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; }
/// <summary> /// Computes what the block version of a newly created block should be, given a previous header and the /// current set of BIP9 deployments defined in the consensus. /// </summary> /// <param name="prevChainedHeader">The header of the previous block in the chain.</param> /// <remarks>This method is currently used during block creation only. Different nodes may not implement /// BIP9, or may disagree about what the current valid set of deployments are. It is therefore not strictly /// possible to validate a block version number in anything more than general terms.</remarks> public int ComputeBlockVersion(ChainedHeader prevChainedHeader) { uint version = ThresholdConditionCache.VersionbitsTopBits; var thresholdConditionCache = new ThresholdConditionCache(this.Parent.Network.Consensus); for (int deployment = 0; deployment < thresholdConditionCache.ArraySize; deployment++) { ThresholdState state = thresholdConditionCache.GetState(prevChainedHeader, deployment); if ((state == ThresholdState.LockedIn) || (state == ThresholdState.Started)) { version |= thresholdConditionCache.Mask(deployment); } } return((int)version); }
protected void ProcessThresholdStateChange(ThresholdState actualPositionSignal, IndicatorDataPoint updated) { if (!Indicator.IsReady) { _previousIndicatorValue = updated.Value; _previousSignal = actualPositionSignal; Signal = _previousSignal; return; } var actualSignal = GetActualSignal(_previousSignal, actualPositionSignal); Signal = actualSignal; _previousIndicatorValue = updated.Value; SurvivalWindow.Add((int)Signal); _previousSignal = actualSignal; }
private int ComputeBlockVersion(ChainedHeader prevChainedHeader, NBitcoin.Consensus consensus) { uint version = ThresholdConditionCache.VersionbitsTopBits; var thresholdConditionCache = new ThresholdConditionCache(consensus); IEnumerable <BIP9Deployments> deployments = Enum.GetValues(typeof(BIP9Deployments)).OfType <BIP9Deployments>(); foreach (BIP9Deployments deployment in deployments) { ThresholdState state = thresholdConditionCache.GetState(prevChainedHeader, deployment); if ((state == ThresholdState.LockedIn) || (state == ThresholdState.Started)) { version |= thresholdConditionCache.Mask(deployment); } } return((int)version); }
// Make sure margin is up-to-date before calling this method. private void UpdateThreshold(IEnumerable <ThingGroupSelector> groupSelectors) { if (!groupSelectors.Any()) { return; } foreach (ThingGroupSelector groupSelector in groupSelectors) { if (groupSelector.UseBottomThreshold) { if (_bottomThresholdLookup.TryGetValue(groupSelector, out ThresholdState state)) { // Only when margin rise from NegBottomThresholdCount to 0 would CanRestock be true, // otherwise, when margin falls from 0 to NegBottomThresholdCount, it is false. if (this.InventoryMargins[groupSelector] >= 0) { state.CanRestock = false; state.NegBottomThresholdCount = groupSelector.BottomThresoldCount - groupSelector.AllowedStackCount; _bottomThresholdLookup[groupSelector] = state; } else { state.NegBottomThresholdCount = groupSelector.BottomThresoldCount - groupSelector.AllowedStackCount; state.CanRestock = state.NegBottomThresholdCount >= this.InventoryMargins[groupSelector] || state.CanRestock; _bottomThresholdLookup[groupSelector] = state; } } else { state = new ThresholdState { NegBottomThresholdCount = groupSelector.BottomThresoldCount - groupSelector.AllowedStackCount, }; state.CanRestock = this.InventoryMargins[groupSelector] <= state.NegBottomThresholdCount; _bottomThresholdLookup[groupSelector] = state; } } else { _bottomThresholdLookup.Remove(groupSelector); } } }
/// <summary> /// Initialize bottom thresholds when pawn is spawned. /// </summary> /// <param name="groupSelectors"> Selectors from loadout. </param> /// <remarks> This function is to make old saves compatible. </remarks> private void InitThreshold(IEnumerable <ThingGroupSelector> groupSelectors) { if (_bottomThresholdLookup.Any()) { return; } foreach (ThingGroupSelector selector in groupSelectors) { if (selector.UseBottomThreshold) { _bottomThresholdLookup[selector] = new ThresholdState() { NegBottomThresholdCount = selector.BottomThresoldCount - selector.AllowedStackCount, CanRestock = true, }; } } }
private int ComputeBlockVersion(ChainedBlock prevChainedBlock, NBitcoin.Consensus consensus) { uint nVersion = ThresholdConditionCache.VERSIONBITS_TOP_BITS; var thresholdConditionCache = new ThresholdConditionCache(consensus); IEnumerable <BIP9Deployments> deploymensts = Enum.GetValues(typeof(BIP9Deployments)) .OfType <BIP9Deployments>(); foreach (BIP9Deployments deployment in deploymensts) { ThresholdState state = thresholdConditionCache.GetState(prevChainedBlock, deployment); if ((state == ThresholdState.LockedIn) || (state == ThresholdState.Started)) { nVersion |= thresholdConditionCache.Mask(deployment); } } return((int)nVersion); }
protected void ProcessThresholdStateChange(ThresholdState actualPositionSignal, IndicatorDataPoint updated) { if (!Indicator.IsReady) { _previousIndicatorValue = updated.Value; _previousSignal = actualPositionSignal; Signal = _previousSignal; return; } var actualSignal = GetActualSignal(_previousSignal, actualPositionSignal); Signal = actualSignal; _previousIndicatorValue = updated.Value; _lastSignals = Utils.shiftRight(_lastSignals); _lastSignals[0] = (int)Signal; _previousSignal = actualSignal; }
protected override bool TickCore(Entity host, RealmTime time, ref object state) { if (state == null) { var stateThresholds = _thresholds.ToList(); state = new ThresholdState() { CurrentThreshold = _thresholds[0], Thresholds = stateThresholds, SelectedState = 0 }; } var tState = state as ThresholdState; if (tState.Thresholds == null) { return(false); } var hpp = (double)(host as Enemy).HP / host.ObjectDesc.MaxHP; if (hpp > tState.CurrentThreshold) { return(false); } SelectedState = tState.SelectedState; if (tState.Thresholds.Count <= 1) { tState.Thresholds = null; } else { tState.Thresholds.RemoveAt(0); tState.CurrentThreshold = tState.Thresholds[0]; tState.SelectedState++; } return(true); }
private SoftForksBip9 CreateSoftForksBip9(ThresholdStateModel metric, ThresholdState state) { var softForksBip9 = new SoftForksBip9() { Status = metric.ThresholdState.ToLower(), Bit = this.Network.Consensus.BIP9Deployments[metric.DeploymentIndex].Bit, StartTime = metric.TimeStart?.ToUnixTimestamp() ?? 0, Timeout = metric.TimeTimeOut?.ToUnixTimestamp() ?? 0, Since = metric.SinceHeight }; if (state == ThresholdState.Started) { softForksBip9.Statistics = new SoftForksBip9Statistics(); softForksBip9.Statistics.Period = metric.ConfirmationPeriod; softForksBip9.Statistics.Threshold = metric.Threshold; softForksBip9.Statistics.Count = metric.Blocks; softForksBip9.Statistics.Elapsed = metric.Height - metric.PeriodStartHeight; softForksBip9.Statistics.Possible = (softForksBip9.Statistics.Period - softForksBip9.Statistics.Threshold) >= (softForksBip9.Statistics.Elapsed - softForksBip9.Statistics.Count); } return(softForksBip9); }
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); }
/// <summary> /// Computes the metrics of all BIP9 deployments for a given block. /// </summary> /// <param name="indexPrev">The block at which to compute the metrics.</param> /// <param name="thresholdStates">The current state of each BIP9 deployment.</param> /// <returns>A <see cref="ThresholdStateModel" /> object containg the metrics.</returns> public List <ThresholdStateModel> GetThresholdStateMetrics(ChainedHeader indexPrev, ThresholdState[] thresholdStates) { var thresholdStateModels = new List <ThresholdStateModel>(); var array = new ThresholdState[this.consensus.BIP9Deployments.Length]; for (var deploymentIndex = 0; deploymentIndex < array.Length; deploymentIndex++) { if (this.consensus.BIP9Deployments[deploymentIndex] == null) { continue; } var deploymentName = this.consensus.BIP9Deployments[deploymentIndex]?.Name; var timeStart = this.consensus.BIP9Deployments[deploymentIndex]?.StartTime.Date; var timeTimeout = this.consensus.BIP9Deployments[deploymentIndex]?.Timeout.Date; var threshold = this.consensus.BIP9Deployments[deploymentIndex].Threshold; var votes = 0; var currentHeight = indexPrev.Height + 1; var period = this.consensus.MinerConfirmationWindow; // First ancestor outside last confirmation window. If we haven't reached block height 2016 yet this will be the genesis block. var periodStart = indexPrev.Height - currentHeight % period > 0 ? indexPrev.Height - currentHeight % period : 0; var periodStartsHeader = indexPrev.GetAncestor(periodStart); var periodEndsHeight = periodStartsHeader.Height + period; var hexVersions = new Dictionary <string, int>(); var totalBlocks = 0; var headerTemp = indexPrev; while (headerTemp != periodStartsHeader) { if (Condition(headerTemp, deploymentIndex)) { votes++; } totalBlocks++; var hexVersion = headerTemp.Header.Version.ToString("X8"); if (!hexVersions.TryGetValue(hexVersion, out var count)) { count = 0; } hexVersions[hexVersion] = count + 1; headerTemp = headerTemp.Previous; } // look in the cache for the hash of the first block an item was deployed var firstSeenHash = this.cache.FirstOrDefault(c => c.Value[deploymentIndex] == ThresholdState.Started); var sinceHeight = 0; if (firstSeenHash.Key != null) { sinceHeight = indexPrev.FindAncestorOrSelf(firstSeenHash.Key).Height; } thresholdStateModels.Add(new ThresholdStateModel { DeploymentName = deploymentName, DeploymentIndex = deploymentIndex, ConfirmationPeriod = period, Blocks = totalBlocks, Votes = votes, HexVersions = hexVersions, TimeStart = timeStart, TimeTimeOut = timeTimeout, Threshold = threshold, Height = currentHeight, SinceHeight = sinceHeight, PeriodStartHeight = periodStartsHeader.Height, PeriodEndHeight = periodEndsHeight, StateValue = thresholdStates[deploymentIndex], ThresholdState = thresholdStates[deploymentIndex].ToString() }); } return(thresholdStateModels); }
/// <summary> /// Computes the metrics of all BIP9 deployments for a given block. /// </summary> /// <param name="indexPrev">The block at which to compute the metrics.</param> /// <param name="thresholdStates">The current state of each BIP9 deployment.</param> /// <returns>A <see cref="ThresholdStateModel" /> object containg the metrics.</returns> public List <ThresholdStateModel> GetThresholdStateMetrics(ChainedHeader indexPrev, ThresholdState[] thresholdStates) { var thresholdStateModels = new List <ThresholdStateModel>(); ThresholdState[] array = new ThresholdState[this.consensus.BIP9Deployments.Length]; for (int deploymentIndex = 0; deploymentIndex < array.Length; deploymentIndex++) { if (this.consensus.BIP9Deployments[deploymentIndex] == null) { continue; } DateTime?timeStart = this.consensus.BIP9Deployments[deploymentIndex]?.StartTime.Date; DateTime?timeTimeout = this.consensus.BIP9Deployments[deploymentIndex]?.Timeout.Date; int threshold = this.consensus.RuleChangeActivationThreshold; int votes = 0; int currentHeight = indexPrev.Height + 1; int period = this.consensus.MinerConfirmationWindow; // First ancestor outside last confirmation window. ChainedHeader periodStartsHeader = indexPrev.GetAncestor(indexPrev.Height - (currentHeight % period)); int periodEndsHeight = periodStartsHeader.Height + period; var hexVersions = new Dictionary <string, int>(); int totalBlocks = 0; while (indexPrev != periodStartsHeader) { if (this.Condition(indexPrev, deploymentIndex)) { votes++; } totalBlocks++; string hexVersion = indexPrev.Header.Version.ToString("X8"); if (!hexVersions.TryGetValue(hexVersion, out int count)) { count = 0; } hexVersions[hexVersion] = count + 1; indexPrev = indexPrev.Previous; } thresholdStateModels.Add(new ThresholdStateModel() { DeploymentIndex = deploymentIndex, ConfirmationPeriod = period, Blocks = totalBlocks, Votes = votes, HexVersions = hexVersions, TimeStart = timeStart, TimeTimeOut = timeTimeout, Threshold = threshold, Height = currentHeight, PeriodStartHeight = periodStartsHeader.Height, PeriodEndHeight = periodEndsHeight, StateValue = thresholdStates[deploymentIndex], ThresholdState = ((ThresholdState)thresholdStates[deploymentIndex]).ToString() }); } return(thresholdStateModels); }
/// <summary> /// Determines the state of a BIP from the cache and/or the chain header history and the corresponding version bits. /// </summary> /// <param name="indexPrev">The previous header of the chain header to determine the states for.</param> /// <param name="deployment">The deployment to check the state of.</param> /// <returns>The current state of the deployment.</returns> public ThresholdState GetState(ChainedHeader indexPrev, int deployment) { int period = this.consensus.MinerConfirmationWindow; int threshold = this.consensus.RuleChangeActivationThreshold; DateTimeOffset?timeStart = this.consensus.BIP9Deployments[deployment]?.StartTime; DateTimeOffset?timeTimeout = this.consensus.BIP9Deployments[deployment]?.Timeout; // Check if this deployment is always active. if (timeStart == Utils.UnixTimeToDateTime(BIP9DeploymentsParameters.AlwaysActive)) { return(ThresholdState.Active); } // 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 (indexPrev != null) { indexPrev = indexPrev.GetAncestor(indexPrev.Height - ((indexPrev.Height + 1) % period)); } // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known. var vToCompute = new List <ChainedHeader>(); while (!this.ContainsKey(indexPrev?.HashBlock, deployment)) { if (indexPrev.GetMedianTimePast() < timeStart) { // Optimization: don't recompute down further, as we know every earlier block will be before the start time. this.Set(indexPrev?.HashBlock, deployment, ThresholdState.Defined); break; } vToCompute.Add(indexPrev); indexPrev = indexPrev.GetAncestor(indexPrev.Height - period); } // At this point, cache[pindexPrev] is known. this.Assert(this.ContainsKey(indexPrev?.HashBlock, deployment)); ThresholdState state = this.Get(indexPrev?.HashBlock, deployment); // Now walk forward and compute the state of descendants of pindexPrev. while (vToCompute.Count != 0) { ThresholdState stateNext = state; indexPrev = vToCompute[vToCompute.Count - 1]; vToCompute.RemoveAt(vToCompute.Count - 1); switch (state) { case ThresholdState.Defined: { if (indexPrev.GetMedianTimePast() >= timeTimeout) { stateNext = ThresholdState.Failed; } else if (indexPrev.GetMedianTimePast() >= timeStart) { stateNext = ThresholdState.Started; } break; } case ThresholdState.Started: { if (indexPrev.GetMedianTimePast() >= timeTimeout) { stateNext = ThresholdState.Failed; break; } // Counts the "votes" in the confirmation window to determine // whether the rule change activation threshold has been met. ChainedHeader pindexCount = indexPrev; int count = 0; for (int i = 0; i < period; i++) { if (this.Condition(pindexCount, deployment)) { count++; } pindexCount = pindexCount.Previous; } // If the threshold has been met then lock in the BIP activation. if (count >= threshold) { 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(indexPrev?.HashBlock, deployment, state = stateNext); } return(state); }
public override sealed void UpdateExtension(TargetConstraint t) { if (!t.joint) { Debug.LogWarning("Angular limit cannot be applied. Missing joint"); return; } if (!t.axis) { Debug.LogWarning("Angular limit cannot be applied. Missing axis"); return; } // Prevent modification t.joint.angularXMotion = ConfigurableJointMotion.Locked; t.joint.angularYMotion = ConfigurableJointMotion.Locked; t.joint.angularZMotion = angularZMotion; // Rotation localRotZ = GetLocalRotZ(t.joint.transform); // Threshold detection if (detectThreshold) { if (togglingThresholdDetectionIn <= 0.0f) { if (localRotZ > threshold && thresholdState != ThresholdState.Over) { togglingThresholdDetectionIn = minTimeBetweenDetections; thresholdState = ThresholdState.Over; onOverThreshold.Invoke(); } else if (localRotZ < threshold && thresholdState != ThresholdState.Under) { togglingThresholdDetectionIn = minTimeBetweenDetections; thresholdState = ThresholdState.Under; onUnderThreshold.Invoke(); } } else { togglingThresholdDetectionIn -= Time.deltaTime; } } // Stucking if (canStuck) { if (breakableJoint == null && stucked) { SetStuck(false, t); stuckingIn = Random.Range(minRandomDuration, maxRandomDuration); } if (!stucked && stuckingIn <= 0.0f) { SetStuck(true, t); } else { stuckingIn -= Time.deltaTime; } } else if (breakableJoint != null) { SetStuck(false, t); } }
/// <summary> /// Computes the metrics of all BIP9 deployments for a given block. /// </summary> /// <param name="indexPrev">The block at which to compute the metrics.</param> /// <param name="thresholdStates">The current state of each BIP9 deployment.</param> /// <returns>A <see cref="ThresholdStateModel" /> object containg the metrics.</returns> public List <ThresholdStateModel> GetThresholdStateMetrics(ChainedHeader indexPrev, ThresholdState[] thresholdStates) { var thresholdStateModels = new List <ThresholdStateModel>(); ThresholdState[] array = new ThresholdState[this.consensus.BIP9Deployments.Length]; for (int deploymentIndex = 0; deploymentIndex < array.Length; deploymentIndex++) { if (this.consensus.BIP9Deployments[deploymentIndex] == null) { continue; } string deploymentName = this.consensus.BIP9Deployments[deploymentIndex]?.Name; DateTime?timeStart = this.consensus.BIP9Deployments[deploymentIndex]?.StartTime.Date; DateTime?timeTimeout = this.consensus.BIP9Deployments[deploymentIndex]?.Timeout.Date; int threshold = this.consensus.RuleChangeActivationThreshold; int votes = 0; int currentHeight = indexPrev.Height + 1; int period = this.consensus.MinerConfirmationWindow; // First ancestor outside last confirmation window. ChainedHeader periodStartsHeader = indexPrev.GetAncestor(indexPrev.Height - (currentHeight % period)); int periodEndsHeight = periodStartsHeader.Height + period; var hexVersions = new Dictionary <string, int>(); int totalBlocks = 0; ChainedHeader headerTemp = indexPrev; while (headerTemp != periodStartsHeader) { if (this.Condition(headerTemp, deploymentIndex)) { votes++; } totalBlocks++; string hexVersion = headerTemp.Header.Version.ToString("X8"); if (!hexVersions.TryGetValue(hexVersion, out int count)) { count = 0; } hexVersions[hexVersion] = count + 1; headerTemp = headerTemp.Previous; } // look in the cache for the hash of the first block an item was deployed var firstSeenHash = this.cache.FirstOrDefault(c => c.Value[deploymentIndex] == ThresholdState.Started); int sinceHeight = 0; if (firstSeenHash.Key != null) { sinceHeight = indexPrev.FindAncestorOrSelf(firstSeenHash.Key).Height; } thresholdStateModels.Add(new ThresholdStateModel() { DeploymentName = deploymentName, DeploymentIndex = deploymentIndex, ConfirmationPeriod = period, Blocks = totalBlocks, Votes = votes, HexVersions = hexVersions, TimeStart = timeStart, TimeTimeOut = timeTimeout, Threshold = threshold, Height = currentHeight, SinceHeight = sinceHeight, PeriodStartHeight = periodStartsHeader.Height, PeriodEndHeight = periodEndsHeight, StateValue = thresholdStates[deploymentIndex], ThresholdState = ((ThresholdState)thresholdStates[deploymentIndex]).ToString() }); } return(thresholdStateModels); }