Пример #1
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);
        }
Пример #2
0
        public static async Task FindStakes(BlockChainParser parser, List <UnspentTransactionData> unspents)
        {
            foreach (var unspent in unspents)
            {
                unspent.blockhash = await parser.GetBlockHash(unspent.txid);

                unspent.blockheight = await parser.Parse(unspent.blockhash);

                await parser.Parse(unspent.blockhash);

                var block = _blockRepository !.GetBlockState(unspent.blockheight);
                unspent.blocktime = block !.bt;
                var output = _transactionRepository !.GetOutput(unspent.txid, unspent.vout);
                unspent.units = output !.units;
            }

            // set negative if expecting a slight increase in POS diff in future:
            var minMarginDifficulty = -0.35f;
            var templates           = new List <MintTemplate>();

            var addresses = unspents.Select(un => un.address)
                            .Distinct()
                            .ToList();

            foreach (var address in addresses)
            {
                var unspentsbyaddress = _transactionRepository !.GetUnspents(address)
                                        .Where(unspent => unspents.Any(u => u.txid == unspent.Id !.Substring(2, 64) && u.vout.ToString() == unspent.Id.Substring(67)))
                                        .ToList();

                unspentsbyaddress.ForEach(unspent =>
                {
                    var mintTemplate = new MintTemplate(
                        unspent.Id,
                        address,
                        unspent.BlockFromTime,
                        unspent.PrevTxOffset,
                        unspent.PrevTxTime,
                        unspent.PrevTxOutIndex,
                        unspent.PrevTxOutValue);

                    mintTemplate.SetBitsWithDifficulty(((Convert.ToSingle(PosDifficulty) - minMarginDifficulty)));

                    if (templates.All(t => t.Id != mintTemplate.Id))
                    {
                        templates.Add(mintTemplate);
                    }
                });
            }

            //load modifiers:
            // start with a block way back assuming there are 6 blocks in an hour:
            // see also: consensus.nStakeTargetSpacing = 10 * 60; // 10-minute block spacing
            var start = BlockHeight - (6 * 24 * 31) - 10;
            var end   = BlockHeight;

            for (var i = start; i < end; i++)
            {
                await parser.Parse(i);
            }

            var futurestakes = await StartSearch(templates);

            ExitWithJson(null, futurestakes);
        }