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); }
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}."); }