public void TargetHashBits_Adjust_OneSixthTime_Validate_HalfAdjustmentLimit() { var thb = HashBits.Create(6, 0xffffffffffffff); var adjustedthb = thb.Adjust(1, 6, 50, HashBits.MinTarget); Assert.AreEqual(6, adjustedthb.GetBitOffset()); Assert.AreEqual(0xaaaaaaaaaaaaaaUL, adjustedthb.GetFraction()); }
public void TargetHashBits_Adjust_SixTime_Validate_HalfAdjustmentLimit() { var thb = HashBits.Create(6, 0xffffffffffffff); var adjustedthb = thb.Adjust(600, 100, 50, HashBits.MinTarget); Assert.AreEqual(5, adjustedthb.GetBitOffset()); Assert.AreEqual(0xbfffffffffffffUL, adjustedthb.GetFraction()); }
public void TargetHashBits_Adjust_ThirthHalfTime_Validate_Offset() { var thb = HashBits.Create(5, 0xffffffffffffff); var adjustedthb = thb.Adjust(3000, 2000, 10000, HashBits.MinTarget); Assert.AreEqual(4, adjustedthb.GetBitOffset()); Assert.IsTrue(thb.GetFraction() > adjustedthb.GetFraction()); }
public void TargetHashBits_Adjust_OneSixthTime_Validate_OffsetAndFraction() { var thb = HashBits.Create(6, 0xffffffffffffff); var adjustedthb = thb.Adjust(1, 6, 10000, HashBits.MinTarget); Assert.AreEqual(8, adjustedthb.GetBitOffset()); Assert.IsTrue(thb.GetFraction() > adjustedthb.GetFraction()); }
public void TargetHashBits_Adjust_SameTime_Validate_OffsetAndFraction() { var thb = HashBits.Create(6, 0xffffffffffffff); var adjustedthb = thb.Adjust(1, 1, 10000, HashBits.MinTarget); Assert.AreEqual(6, adjustedthb.GetBitOffset()); Assert.AreEqual(thb.GetFraction(), adjustedthb.GetFraction()); }
public void TargetHashBits_Adjust_DoubleMinusTime_FullFraction_Validate_OffsetAndFraction() { var thb = HashBits.Create(2, 0xffffffffffffff); var adjustedthb = thb.Adjust(1999, 1000, 10000, HashBits.MinTarget); Assert.AreEqual(1, adjustedthb.GetBitOffset()); Assert.IsTrue(thb.GetFraction() > adjustedthb.GetFraction()); }
public void TargetHashBits_Adjust_SixTime_Validate_MinimumTarget() { var thb = HashBits.Create(6, 0xffffffffffffff); var minTarget = HashBits.Create(0x0f, 0xffffffffffffff); var adjustedthb = thb.Adjust(600, 100, 50, minTarget); Assert.AreEqual(minTarget.GetBitOffset(), adjustedthb.GetBitOffset()); Assert.AreEqual(minTarget.GetFraction(), adjustedthb.GetFraction()); }
public void TargetHashBits_Adjust_HalfMinusTime_Validate_OffsetAndFraction() { var thb = HashBits.Create(6, 0xffffffffffffff); var adjustedthb = thb.Adjust(99, 200, 10000, HashBits.MinTarget); var hash = adjustedthb.ToHash().SerializeToJson(); Console.WriteLine($"o({adjustedthb.GetBitOffset()}),\tf(0x{adjustedthb.GetFraction():X16}),\th({hash})"); Assert.AreEqual(7, adjustedthb.GetBitOffset()); Assert.IsTrue(thb.GetFraction() > adjustedthb.GetFraction()); }
public void TargetHashBits_Adjust__Smoke_ConsoleOutput() { var target = 10; var thb = HashBits.Create(100, 0xffffffffffffff); //var thb = new TargetHashBits(100, 0x88888888888888); for (int i = 1; i <= 40; i++) { var adjustedthb = thb.Adjust(i, target, 10000); var hash = adjustedthb.ToHash().SerializeToJson(); Console.WriteLine($"{i}/{target}:\to({adjustedthb.GetBitOffset()}),\tf(0x{adjustedthb.GetFraction():X16}),\th({hash})"); } }
public void TargetHashBits_ToHash_Offset200_Validate_Segments() { var thb = HashBits.Create(200, 0x123456789abcde); var hash = thb.ToHash(); Assert.AreEqual(0x00, hash.Value[24]); Assert.AreEqual(0x12, hash.Value[25]); Assert.AreEqual(0x34, hash.Value[26]); Assert.AreEqual(0x56, hash.Value[27]); Assert.AreEqual(0x78, hash.Value[28]); Assert.AreEqual(0x9a, hash.Value[29]); Assert.AreEqual(0xbc, hash.Value[30]); Assert.AreEqual(0xde, hash.Value[31]); }
public void TargetHashBits_ToHash_Offset0_Validate_Segments() { var thb = HashBits.Create(0, 0x123456789abcde); var hash = thb.ToHash(); Assert.AreEqual(0x12, hash.Value[0]); Assert.AreEqual(0x34, hash.Value[1]); Assert.AreEqual(0x56, hash.Value[2]); Assert.AreEqual(0x78, hash.Value[3]); Assert.AreEqual(0x9a, hash.Value[4]); Assert.AreEqual(0xbc, hash.Value[5]); Assert.AreEqual(0xde, hash.Value[6]); Assert.AreEqual(0x00, hash.Value[7]); }
public void TargetHashBits_ToHash_Offset193_Validate_Segments() { var thb = HashBits.Create(193, 0xffffffffffffff); var hash = thb.ToHash(); Assert.AreEqual(0x00, hash.Value[23]); Assert.AreEqual(0x7f, hash.Value[24]); Assert.AreEqual(0xff, hash.Value[25]); Assert.AreEqual(0xff, hash.Value[26]); Assert.AreEqual(0xff, hash.Value[27]); Assert.AreEqual(0xff, hash.Value[28]); Assert.AreEqual(0xff, hash.Value[29]); Assert.AreEqual(0xff, hash.Value[30]); Assert.AreEqual(0x80, hash.Value[31]); }
public void TargetHashBits_ToHash_Offset4_Validate_Segments() { var thb = HashBits.Create(4, 0xffffffffffffff); var hash = thb.ToHash(); Assert.AreEqual(0x0f, hash.Value[0]); Assert.AreEqual(0xff, hash.Value[1]); Assert.AreEqual(0xff, hash.Value[2]); Assert.AreEqual(0xff, hash.Value[3]); Assert.AreEqual(0xff, hash.Value[4]); Assert.AreEqual(0xff, hash.Value[5]); Assert.AreEqual(0xff, hash.Value[6]); Assert.AreEqual(0xf0, hash.Value[7]); Assert.AreEqual(0x00, hash.Value[8]); }
public void TargetHashBits_ToHash_Offset201_Validate_ArgumentException() { var thb = HashBits.Create(201, 0xffffffffffffff); var hash = thb.ToHash(); //Checked only if TargetHashBits has no limit on offset Assert.AreEqual(0x00, hash.Value[24]); Assert.AreEqual(0x7f, hash.Value[25]); Assert.AreEqual(0xff, hash.Value[26]); Assert.AreEqual(0xff, hash.Value[27]); Assert.AreEqual(0xff, hash.Value[28]); Assert.AreEqual(0xff, hash.Value[29]); Assert.AreEqual(0xff, hash.Value[30]); Assert.AreEqual(0xff, hash.Value[31]); //Assert.AreEqual(0x80, hash.Value[32]);//We loose this bits }
private void AddTasks(int taskCount) { _feedback.Execute("AddTasks", () => { for (var i = 0; i < taskCount; i++) { var cancelationTokenSource = new CancellationTokenSource(); var task = new MinerTask(cancelationTokenSource); var nounce = _nextNounce; task.Start(cancellationToken => FindHashTarget( HashBits.Create(HashBits.OffsetMax, nounce), NounceStep, cancellationToken)); _tasks.Enqueue(task); _nextNounce += NounceStep; } }, () => $"{nameof(taskCount)}: {taskCount}"); }
public static HashBits Adjust(this HashBits @this, long currentTimeDelta, long targetTimeDelta, int adjustmentPercentLimit = Genesis.AdjustmentPercentLimit, HashBits minTarget = null) { minTarget = minTarget ?? Genesis.Target; //Adjustment log /*var coefficient = (decimal)targetTimeDelta / currentTimeDelta; * Console.WriteLine($"@@@"); * Console.WriteLine($"@ Adjustment -> currentTimeDelta: {TimeSpan.FromTicks(currentTimeDelta)}, targetTimeDelta: {TimeSpan.FromTicks(targetTimeDelta)}, Expected coefficient: {coefficient}");*/ if (targetTimeDelta != currentTimeDelta) { int offsetAdjust = 0; ulong fractionAdjust; if (targetTimeDelta < currentTimeDelta) { var limit = targetTimeDelta + targetTimeDelta * adjustmentPercentLimit / 100; // X(1+A) if (currentTimeDelta > limit) { currentTimeDelta = limit; } while (targetTimeDelta < currentTimeDelta) { targetTimeDelta <<= 1; offsetAdjust -= 1; } // TODO: optimize using intermediate bit shifts instead of floating calculations //Because fraction offset was moved above the target (by power of 2), //reduce fraction itself with (1/2 < fractionMultiplyer < 1) to match the exact target var fractionMultiplyer = (decimal)currentTimeDelta / targetTimeDelta; //Because last byte of the fraction is reserved for offset, there will be a space for one bit shift //so fraction can be normalized even if high bit goes away from fraction reduction fractionAdjust = (ulong)((@this.GetFraction() << 1) * fractionMultiplyer); offsetAdjust++; } else { var limit = targetTimeDelta * 100 / (100 + adjustmentPercentLimit); // X/(1+A) if (currentTimeDelta < limit) { currentTimeDelta = limit; } while (currentTimeDelta < targetTimeDelta) { currentTimeDelta <<= 1; offsetAdjust += 1; } // TODO: optimize using intermediate bit shifts instead of floating calculations //Because fraction offset was moved below the target (by power of 2), //increase fraction itself with (1 < fractionMultiplyer < 2) to match the exact target var fractionMultiplyer = (decimal)currentTimeDelta / targetTimeDelta; //Because last byte of the fraction is reserved for offset, there will be a space for one bit if necessary fractionAdjust = (ulong)(@this.GetFraction() * fractionMultiplyer); } // In case fraction was increased Adjust(Normalize) fraction/offset to match their masks if ((fractionAdjust & HashBits.OffsetMask) != 0) { fractionAdjust >>= 1; offsetAdjust--; } var newOffset = @this.GetBitOffset() + offsetAdjust; //Adjustment log /*var currentCoefficient = ((decimal) GetFraction() / fractionAdjust) * (decimal)Math.Pow(2, -(GetBitOffset()- newOffset)); * Console.WriteLine($"@ Adjustment -> Current: {currentCoefficient} (o:{newOffset:x1}, f:{fractionAdjust:x16})");*/ if (newOffset < minTarget.GetBitOffset()) { return(minTarget); } else if (newOffset > HashBits.OffsetMax) { return(HashBits.Create(HashBits.OffsetMax, fractionAdjust >> (newOffset - HashBits.OffsetMax))); } return(HashBits.Create((byte)newOffset, fractionAdjust)); } return(@this); }