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");
            }
        }
Example #8
0
        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;
            }
        }
Example #9
0
        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);
        }