Example #1
0
        bool CheckStakeKernelHash(SegWitCoin segWitCoin)
        {
            BigInteger value          = BigInteger.ValueOf(segWitCoin.UtxoValue);
            BigInteger weightedTarget = this.PosV3.TargetAsBigInteger.Multiply(value);

            uint256 kernelHash;

            using (var ms = new MemoryStream())
            {
                var serializer = new BitcoinStream(ms, true);
                serializer.ReadWrite(this.PosV3.StakeModifierV2);

                if (C.Network.CreateTransaction() is PosTransaction)
                {
                    //serializer.ReadWrite(stakingCoin.Time); // be sure this is uint
                    var oldFunnyTime = this.nodeServices.CoinView.FetchCoins(new[] { segWitCoin.UtxoTxHash }).UnspentOutputs[0].Time;
                    serializer.ReadWrite(oldFunnyTime); // it should be block time, but due to a bug in ppcoin we need oldFunnyTime
                }

                serializer.ReadWrite(segWitCoin.UtxoTxHash);
                serializer.ReadWrite(segWitCoin.UtxoTxN);
                serializer.ReadWrite((uint)this.PosV3.CurrentBlockTime); // be sure this is uint
                kernelHash = Hashes.Hash256(ms.ToArray());
            }

            var hash = new BigInteger(1, kernelHash.ToBytes(false));

            return(hash.CompareTo(weightedTarget) <= 0);
        }
Example #2
0
        void CreateNextBlock(BlockTemplate blockTemplate, List <SegWitCoin> kernelCoins)
        {
            SegWitCoin kernelCoin = kernelCoins[0];

            foreach (var coin in kernelCoins)
            {
                if (coin.UtxoValue < kernelCoin.UtxoValue)
                {
                    kernelCoin = coin;
                }
            }

            var newBlockHeight = this.nodeServices.ConsensusManager.Tip.Height + 1;

            var totalReward = blockTemplate.TotalFee + this.nodeServices.PosCoinviewRule.GetProofOfStakeReward(newBlockHeight);

            blockTemplate.Block.Header.Time = (uint)this.PosV3.CurrentBlockTime;

            Transaction tx = CoinstakeTransactionService.CreateAndSignCoinstakeTransaction(kernelCoin, totalReward.Satoshi, (uint)this.PosV3.CurrentBlockTime, this.passphrase, out Key blockSignatureKey);

            if (tx is PosTransaction posTransaction)
            {
                ((PosTransaction)blockTemplate.Block.Transactions[0]).Time = (uint)this.PosV3.CurrentBlockTime;
            }

            blockTemplate.Block.Transactions.Insert(1, tx);

            this.nodeServices.BlockProvider.BlockModified(this.nodeServices.ConsensusManager.Tip, blockTemplate.Block);

            ECDSASignature signature = blockSignatureKey.Sign(blockTemplate.Block.GetHash());

            ((PosBlock)blockTemplate.Block).BlockSignature = new BlockSignature {
                Signature = signature.ToDER()
            };

            ChainedHeader chainedHeader;

            try
            {
                chainedHeader = this.nodeServices.ConsensusManager.BlockMinedAsync(blockTemplate.Block).GetAwaiter().GetResult();
            }
            catch (Exception)
            {
                this.Status.BlocksNotAccepted++;
                throw;
            }

            if (chainedHeader == null)
            {
                this.Status.BlocksNotAccepted += 1;
                return;
            }

            if (this.LastStakedBlock.BlockTime != 0)
            {
                this.Status.ActualTime = (int)(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - this.LastStakedBlock.BlockTime);
            }
            else
            {
                this.Status.ActualTime = (int)(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - this.Status.StartedUtc);
            }

            this.LastStakedBlock.Hash               = chainedHeader.HashBlock;
            this.LastStakedBlock.Height             = chainedHeader.Height;
            this.LastStakedBlock.BlockSize          = chainedHeader.Block.BlockSize ?? -1;
            this.LastStakedBlock.TxId               = chainedHeader.Block.Transactions[1].GetHash();
            this.LastStakedBlock.Transactions       = chainedHeader.Block.Transactions.Count;
            this.LastStakedBlock.TotalReward        = totalReward;
            this.LastStakedBlock.KernelAddress      = kernelCoin.SegWitAddress.Address;
            this.LastStakedBlock.WeightUsed         = kernelCoin.UtxoValue;
            this.LastStakedBlock.TotalComputeTimeMs = this.stopwatch.ElapsedMilliseconds;
            this.LastStakedBlock.BlockTime          = this.PosV3.CurrentBlockTime;
            this.Status.BlocksAccepted             += 1;

            Log.Logger.LogInformation(
                $"Congratulations, your staked a new block at height {newBlockHeight} and received a total reward of {totalReward} {C.Network.CoinTicker}.");
        }