private bool IncTest(long num) { var b0 = new BigInteger(num); var c0 = Mint.BigToCompact(b0); BigInteger b1; if (num < 0x800000) { b1 = new BigInteger(num + 1); } else { b1 = new BigInteger(num); var bytes = BigInteger.Abs(b1).ToByteArray().Length; var leftshift = 8 * (bytes - 3); var toadd = 1 << leftshift; b1 = BigInteger.Add(b1, new BigInteger(toadd)); } var c1 = Mint.BigToCompact(b1); if (c1 == c0) { return(false); } var newC1 = Mint.IncCompact(c0); return(newC1 == c1); }
/// <summary> /// https://github.com/kac-/umint/blob/master/ukernel_test.go /// </summary> public void CheckStakeKernelHashTest() { var result = Mint.CheckStakeKernelHash(new MintTemplate( "totest", "Pxxxx", 1394219584, 160, 1394219584, 1, 210090000, 471087779 ), 1411634680, 15161125480764745506, 2592000); bool isValid = result.success; AssertThrow(isValid, "CheckStakeKernelHash failed"); var tpl0Hash = new List <byte> { 0x00, 0x00, 0x00, 0xdb, 0x33, 0x30, 0x88, 0x15, 0x19, 0xa4, 0xf3, 0x2b, 0x90, 0x91, 0xb0, 0x93, 0x0f, 0x24, 0xec, 0x6f, 0xb0, 0x90, 0x0a, 0xcf, 0xbf, 0xb0, 0xc2, 0x26, 0xc7, 0xbc, 0x31, 0x92, }; //little endian tpl0Hash.Reverse(); for (int i = 0; i < result.hash.Length; i++) { isValid = result.hash[i] == tpl0Hash[i]; AssertThrow(isValid, "CheckStakeKernelHash part 2 failed"); } // check if template satisfies min target var minbits = Mint.IncCompact(Mint.BigToCompact(result.minTarget)); var minresult = Mint.CheckStakeKernelHash(new MintTemplate( "totest", "Pxxx", 1394219584, 160, 1394219584, 1, 210090000, minbits ), 1411634680, 15161125480764745506, 2592000); isValid = minresult.success; AssertThrow(isValid, "CheckStakeKernelHash part 3 failed"); }
/// <summary> /// https://github.com/kac-/umint/blob/master/mint_test.go /// </summary> public void TestRoundtrip() { var set = new List <uint> { 471105047 }; set.ForEach(compact => { var expected = Mint.BigToCompact(Mint.DiffToTarget(Mint.CompactToDiff(compact))); bool isValid = compact == expected; AssertThrow(isValid, "TestRoundtrip failed"); }); }
public static async Task <IReadOnlyList <PossibleStake> > StartSearch(List <MintTemplate> templates) { var lastblock = _blockRepository !.GetBlockState(BlockHeight - 6); //not the very last var lastblocktime = lastblock !.bt; var currentTime = ConvertToUnixTimestamp(DateTime.UtcNow); var start = currentTime; var end = lastblocktime + Findstakelimit; var blockModifiers = _blockRepository.GetStakeModifiers(lastblock.h); var results = new List <CheckStakeResult>(); var resultsStakes = new List <PossibleStake>(); for (var timestamp = start; timestamp < end; timestamp++) { var modifier = Mint.GetModifier(blockModifiers, timestamp, Findstakelimit); foreach (var template in templates) { var result = Mint.CheckStakeKernelHash(template, timestamp, modifier !.stakeModifier, StakeMinAge); switch (result.success) { case true when results.All(r => r.Id != template.Id && r.FutureTimestamp != timestamp): // Console.WriteLine(" " + template.OfAddress + ": " + ConvertFromUnixTimestamp(timestamp) + " difficulty: " + result.minimumDifficulty.ToString("0.00")); result.StakeModifierHex = modifier !.mr; results.Add(new CheckStakeResult { Id = template.Id, OfAddress = template.OfAddress, minimumDifficulty = result.minimumDifficulty, FutureTimestamp = timestamp, StakeModifier = result.StakeModifier, StakeModifierHex = modifier !.mr, BlockFromTime = result.BlockFromTime, PrevTxOffset = result.PrevTxOffset, PrevTxTime = result.PrevTxTime }); resultsStakes = await EnrichWithTemplateData(resultsStakes, templates, result, template.PrevTxOutValue); //ExportResults(resultsStakes, results); break; } } }
public void BigToCompactTest() { var set = new[] { new uint[] { 8388608, 67141632 }, }; foreach (var i in set) { // ReSharper disable once RedundantCast long data = (long)i[0]; var b0 = new BigInteger(data); var c0 = Mint.BigToCompact(b0); // ReSharper disable once RedundantCast uint encoded = (uint)i[1]; bool isValid = c0 == encoded; AssertThrow(isValid, "BigToCompactTest failed"); } }
public void ShouldCovertToCompact() { var dataset = new[] { new long[] { 7, 16842752 }, new long[] { 734, 16842754 }, new long[] { 42, 16842752 }, new long[] { 1984, 16842759 } }; foreach (var i in dataset) { var data = (uint)i[0]; var expected = i[1]; var bn = Mint.IncCompact(data); bool isValid = bn == expected; AssertThrow(isValid, "ShouldCovertToCompact failed"); } }
public void ShouldCovertToTarget() { var set = new[] { new object[] { 21.345F, "1263037534708007065233903449077122707924414303996398674892185141248" }, new object[] { 6.15F, "4383664314154799371057726451385090274339071401122701325781576974336" }, new object[] { 56.08F, "480733493559447088382085585624766859301132742736115421675251564544" }, new object[] { 18.5007F, "1457217015401058230710519728509336428455980242272185129797989433344" }, new object[] { 7F, "3851362069648898194808762653391849309347085353924666742105907920896" } }; foreach (var i in set) { float data = (float)i[0]; string encoded = (string)i[1]; var bn = Mint.DiffToTarget(data); bool isValid = bn.ToString() == encoded; AssertThrow(isValid, "ShouldCovertToTarget failed"); } }
public async Task Parse(uint height, List <string> txIds, uint blocktime) { // ReSharper disable once RedundantCast var sizeVarintTx = Mint.GetSizeVarInt((long)(txIds.Count)); var offset = PeercoinConstants.BlockHeaderSize + sizeVarintTx; for (int index = 0; index < txIds.Count; index++) { var tx = await client.GetRawTransaction(txIds[index]); var txraw = await client.DecodeRawTransaction(tx.hex); var rawsize = tx.hex.Length / 2; // 2 char is 1 byte StoreTxState(blocktime, height, txraw, (uint)index, offset, (uint)rawsize); DeleteSpentFromStore(txraw); ParseVouts(txraw); offset += rawsize; } }
public static CheckStakeResult CheckStakeKernelHash(MintTemplate template, uint txTime, ulong stakeModifier, uint stakeMinAge) { var retobj = new CheckStakeResult { Id = template.Id, OfAddress = template.OfAddress, StakeModifier = stakeModifier, BlockFromTime = template.BlockFromTime, PrevTxOffset = template.PrevTxOffset, PrevTxTime = template.PrevTxTime, PrevTxOutIndex = template.PrevTxOutIndex, FutureTimestamp = txTime, }; if (txTime < template.PrevTxTime) { // Transaction timestamp violation return(retobj); } if (template.BlockFromTime + stakeMinAge > txTime) { // Min age requirement return(retobj); } var bnTargetPerCoinDay = Mint.CompactToBig(template.Bits !.Value); long nTimeWeight = txTime - template.PrevTxTime; if (nTimeWeight > PeercoinConstants.StakeMaxAge) { nTimeWeight = PeercoinConstants.StakeMaxAge; } long timeReduction = stakeMinAge; nTimeWeight -= timeReduction; var t1 = new BigInteger(24 * 60 * 60); var t2 = new BigInteger(PeercoinConstants.Coin); var t3 = new BigInteger(template.PrevTxOutValue); var t4 = new BigInteger(nTimeWeight); BigInteger bnCoinDayWeight = (((t3 * t4) / t2)) / t1; BigInteger targetInt = bnCoinDayWeight * (bnTargetPerCoinDay); //byte[] array = new byte[28]; var buffer = new byte[28]; var bufferindex = 0; byte[] arrStakemodifier = BitConverter.GetBytes(stakeModifier); //put stakemodifier in buffer for (var i = 0; i < 8; i++) { buffer[bufferindex] = arrStakemodifier[i]; bufferindex++; } new List <uint> { (uint)template.BlockFromTime, (uint)template.PrevTxOffset, (uint)template.PrevTxTime, (uint)template.PrevTxOutIndex, (uint)txTime } .ForEach(num => { var dn = num; for (var i = 0; i < 4; i++) { buffer[bufferindex] = (byte)(dn & 0xff); dn >>= 8; bufferindex++; } }); //no reverse so keep it in little endian var hashProofOfStake = Mint.DoubleSha256(buffer.ToList()).ToArray(); //keep it in little-endian .Reverse().ToArray(); //add zero to last in array to make it unsigned: // https://docs.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.-ctor?view=netframework-4.5.2#System_Numerics_BigInteger__ctor_System_Byte___ var lastindex = hashProofOfStake.Length - 1; if ((hashProofOfStake[lastindex] & 0x80) > 0) { byte[] temp = new byte[hashProofOfStake.Length]; Array.Copy(hashProofOfStake, temp, hashProofOfStake.Length); hashProofOfStake = new byte[temp.Length + 1]; Array.Copy(temp, hashProofOfStake, temp.Length); } var hashProofOfStakeInt = new BigInteger(hashProofOfStake); if (hashProofOfStakeInt > targetInt) { return(retobj); } //yeah, below target! retobj.minTarget = (hashProofOfStakeInt / bnCoinDayWeight) - new BigInteger(1); retobj.success = true; retobj.hash = hashProofOfStake; retobj.Id = template.Id; var comp = Mint.IncCompact( Mint.BigToCompact(retobj.minTarget) ); retobj.minimumDifficulty = Mint.CompactToDiff(comp); return(retobj); }