Commit 2d4e72d3 authored by Sergei Zubov's avatar Sergei Zubov

Fix mining on PoS network

From stratis PR#1634, commit df43989243138c05fb23cd549b7b71f60a336e35
parent 00b2e5bd
This diff is collapsed.
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using NBitcoin.BouncyCastle.Math;
using NBitcoin.DataEncoders;
using NBitcoin.Protocol;
namespace NBitcoin.Networks
......@@ -12,8 +9,9 @@ namespace NBitcoin.Networks
{
public DeStreamTest() //: base()
{
string InitialWalletAddress = "TPPL2wmtxGzP8U6hQsGkRA9yCMsazB33ft";
decimal InitialCoins = 6000000000;
const string initialWalletAddress = "TAE5v2wDwkrCPTDN51ru4YSZ8KvnFFrUQc";
const decimal initialCoins = 6000000000;
const int numberOfEmissionTransactions = 6;
// The message start string is designed to be unlikely to occur in normal data.
// The characters are rarely used upper ASCII, not valid as UTF-8, and produce
......@@ -31,27 +29,29 @@ namespace NBitcoin.Networks
this.RPCPort = 0xDE10; // 56848,
this.CoinTicker = "TDST";
this.Consensus.PowLimit = new Target(new uint256("0000ffff00000000000000000000000000000000000000000000000000000000"));
this.Consensus.DefaultAssumeValid = new uint256("0x98fa6ef0bca5b431f15fd79dc6f879dc45b83ed4b1bbe933a383ef438321958e"); // 372652
this.Consensus.PowLimit =
new Target(new uint256("0000ffff00000000000000000000000000000000000000000000000000000000"));
this.Consensus.PowTargetTimespan = TimeSpan.FromSeconds(14 * 24 * 60 * 60); // two weeks
this.Consensus.PowTargetSpacing = TimeSpan.FromSeconds(10 * 60);
this.Consensus.PowAllowMinDifficultyBlocks = false;
this.Consensus.PowNoRetargeting = false;
this.Consensus.RuleChangeActivationThreshold = 1916; // 95% of 2016
this.Consensus.MinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
this.Consensus.LastPOWBlock = 12500;
this.Consensus.DefaultAssumeValid =
new uint256("0x98fa6ef0bca5b431f15fd79dc6f879dc45b83ed4b1bbe933a383ef438321958e"); // 372652
this.Consensus.CoinbaseMaturity = 10;
this.Consensus.MaxMoney = long.MaxValue;
this.Consensus.ProofOfWorkReward = Money.Zero;
this.Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS] = new byte[] { (65) };
this.Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS] = new byte[] { (196) };
this.Base58Prefixes[(int)Base58Type.SECRET_KEY] = new byte[] { (65 + 128) };
this.Base58Prefixes[(int) Base58Type.PUBKEY_ADDRESS] = new byte[] {65};
this.Base58Prefixes[(int) Base58Type.SCRIPT_ADDRESS] = new byte[] {196};
this.Base58Prefixes[(int) Base58Type.SECRET_KEY] = new byte[] {65 + 128};
this.Checkpoints = new Dictionary<int, CheckpointInfo>
{
{ 0, new CheckpointInfo(new uint256("0x00000e246d7b73b88c9ab55f2e5e94d9e22d471def3df5ea448f5576b1d156b9"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) },
{ 2, new CheckpointInfo(new uint256("0x56959b1c8498631fb0ca5fe7bd83319dccdc6ac003dccb3171f39f553ecfa2f2"), new uint256("0x13f4c27ca813aefe2d9018077f8efeb3766796b9144fcc4cd51803bf4376ab02")) },
{ 50000, new CheckpointInfo(new uint256("0xb42c18eacf8fb5ed94eac31943bd364451d88da0fd44cc49616ffea34d530ad4"), new uint256("0x824934ddc5f935e854ac59ae7f5ed25f2d29a7c3914cac851f3eddb4baf96d78")) },
{ 100000, new CheckpointInfo(new uint256("0xf9e2f7561ee4b92d3bde400d251363a0e8924204c326da7f4ad9ccc8863aad79"), new uint256("0xdef8d92d20becc71f662ee1c32252aca129f1bf4744026b116d45d9bfe67e9fb")) },
{ 150000, new CheckpointInfo(new uint256("0x08b7c20a450252ddf9ce41dbeb92ecf54932beac9090dc8250e933ad3a175381"), new uint256("0xf05dad15f733ae0acbd34adc449be9429099dbee5fa9ecd8e524cf28e9153adb")) },
{ 200000, new CheckpointInfo(new uint256("0x8609cc873222a0573615788dc32e377b88bfd6a0015791f627d969ee3a415115"), new uint256("0xfa28c1f20a8162d133607c6a1c8997833befac3efd9076567258a7683ac181fa")) },
{ 250000, new CheckpointInfo(new uint256("0xdd664e15ac679a6f3b96a7176303956661998174a697ad8231f154f1e32ff4a3"), new uint256("0x19fc0fa29418f8b19cbb6557c1c79dfd0eff6779c0eaaec5d245c5cdf3c96d78")) },
{ 300000, new CheckpointInfo(new uint256("0x2409eb5ae72c80d5b37c77903d75a8e742a33843ab633935ce6e5264db962e23"), new uint256("0xf5ec7af55516b8e264ed280e9a5dba0180a4a9d3713351bfea275b18f3f1514e")) },
{ 350000, new CheckpointInfo(new uint256("0x36811041e9060f4b4c26dc20e0850dca5efaabb60618e3456992e9c0b1b2120e"), new uint256("0xbfda55ef0756bcee8485e15527a2b8ca27ca877aa09c88e363ef8d3253cdfd1c")) },
{ 400000, new CheckpointInfo(new uint256("0xb6abcb933d3e3590345ca5d3abb697461093313f8886568ac8ae740d223e56f6"), new uint256("0xfaf5fcebee3ec0df5155393a99da43de18b12e620fef5edb111a791ecbfaa63a")) }
};
this.Checkpoints = new Dictionary<int, CheckpointInfo>();
// TODO: Add genesis and premine block to Checkpoints
// First parameter - block height
// { 0, new CheckpointInfo(new uint256("0x00000e246d7b73b88c9ab55f2e5e94d9e22d471def3df5ea448f5576b1d156b9"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) },
this.DNSSeeds = new List<DNSSeedData>
{
......@@ -69,17 +69,19 @@ namespace NBitcoin.Networks
this.GenesisNonce = 1831645;
this.GenesisBits = 0x1e0fffff;
this.GenesisVersion = 1;
this.GenesisReward = Money.Coins(InitialCoins);
this.GenesisWalletAddress = InitialWalletAddress;
this.GenesisReward = Money.Coins(initialCoins);
this.GenesisWalletAddress = initialWalletAddress;
this.Genesis = CreateDeStreamGenesisBlock(this.Consensus.ConsensusFactory, this.GenesisTime, this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward, this.GenesisWalletAddress);
this.Genesis.Header.Time = 1493909211;
this.Genesis = this.CreateDeStreamGenesisBlock(this.Consensus.ConsensusFactory, this.GenesisTime,
this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward,
this.GenesisWalletAddress, numberOfEmissionTransactions);
this.Genesis.Header.Time = (uint) new DateTimeOffset(2018,09,24,16,13,00, TimeSpan.FromHours(3)).ToUnixTimeSeconds();
this.Genesis.Header.Nonce = 2433759;
this.Genesis.Header.Bits = this.Consensus.PowLimit;
this.Consensus.HashGenesisBlock = this.Genesis.GetHash();
// Assert(this.Consensus.HashGenesisBlock == uint256.Parse("c5974b227ccb19ebd97578285a5937bb4bfb6dcdbf473966d8a2f9c714a8dbb0"));
// Assert(this.Genesis.Header.HashMerkleRoot == uint256.Parse("9e3fff58fb1ba15a69198e22d99572fa024afb754bfe1d3b8d28b86fd9de62df"));
// Assert(this.Consensus.HashGenesisBlock == uint256.Parse("c5974b227ccb19ebd97578285a5937bb4bfb6dcdbf473966d8a2f9c714a8dbb0"));
// Assert(this.Genesis.Header.HashMerkleRoot == uint256.Parse("9e3fff58fb1ba15a69198e22d99572fa024afb754bfe1d3b8d28b86fd9de62df"));
}
}
}
\ No newline at end of file
......@@ -8,17 +8,24 @@ namespace Stratis.Bitcoin.Features.Miner
/// <inheritdoc/>
public sealed class BlockProvider : IBlockProvider
{
private readonly Network network;
/// <summary>Defines how proof of work blocks are built.</summary>
private readonly PowBlockDefinition powBlockDefinition;
/// <summary>Defines how proof of stake blocks are built.</summary>
private readonly PosBlockDefinition posBlockDefinition;
/// <summary>Defines how proof of work blocks are built on a Proof-of-Stake network.</summary>
private readonly PosPowBlockDefinition posPowBlockDefinition;
/// <param name="definitions">A list of block definitions that the builder can utilize.</param>
public BlockProvider(IEnumerable<BlockDefinition> definitions)
public BlockProvider(Network network, IEnumerable<BlockDefinition> definitions)
{
this.network = network;
this.powBlockDefinition = definitions.OfType<PowBlockDefinition>().FirstOrDefault();
this.posBlockDefinition = definitions.OfType<PosBlockDefinition>().FirstOrDefault();
this.posPowBlockDefinition = definitions.OfType<PosPowBlockDefinition>().FirstOrDefault();
}
/// <inheritdoc/>
......@@ -30,6 +37,9 @@ namespace Stratis.Bitcoin.Features.Miner
/// <inheritdoc/>
public BlockTemplate BuildPowBlock(ChainedHeader chainTip, Script script)
{
if (this.network.Consensus.IsProofOfStake)
return this.posPowBlockDefinition.Build(chainTip, script);
return this.powBlockDefinition.Build(chainTip, script);
}
}
......
......@@ -9,19 +9,19 @@ namespace Stratis.Bitcoin.Features.Miner.Interfaces
/// Generates up to a specified number of blocks with a limited number of attempts.
/// </summary>
/// <param name="reserveScript">The reserve script.</param>
/// <param name="generate">Number of blocks to generate. It is possible that less than the required number of blocks will be mined.</param>
/// <param name="amountOfBlocksToMine">Number of blocks to generate. It is possible that less than the required number of blocks will be mined.</param>
/// <param name="maxTries">Maximum number of attempts the miner will calculate PoW hash in order to find suitable ones to generate specified amount of blocks.</param>
/// <returns>List with generated block's hashes</returns>
List<uint256> GenerateBlocks(ReserveScript reserveScript, ulong generate, ulong maxTries);
List<uint256> GenerateBlocks(ReserveScript reserveScript, ulong amountOfBlocksToMine, ulong maxTries);
/// <summary>
/// Increments or resets the extra nonce based on the previous hash block value on on the pow miner and the passed nExtraNonce.
/// </summary>
/// <param name="pblock">The template block.</param>
/// <param name="pindexPrev">The previous chained block.</param>
/// <param name="nExtraNonce">The extra nonce counter.</param>
/// <param name="block">The template block.</param>
/// <param name="previousHeader">The previous chained block.</param>
/// <param name="extraNonce">The extra nonce counter.</param>
/// <returns>The new extra nonce after incrementing.</returns>
int IncrementExtraNonce(Block pblock, ChainedHeader pindexPrev, int nExtraNonce);
int IncrementExtraNonce(Block block, ChainedHeader previousHeader, int extraNonce);
/// <summary>
/// Starts a new async mining loop or returns the existing running mining loop.
......
......@@ -254,6 +254,7 @@ namespace Stratis.Bitcoin.Features.Miner
services.AddSingleton<IBlockProvider, BlockProvider>();
services.AddSingleton<BlockDefinition, PowBlockDefinition>();
services.AddSingleton<BlockDefinition, PosBlockDefinition>();
services.AddSingleton<BlockDefinition, PosPowBlockDefinition>();
services.AddSingleton<MinerController>();
services.AddSingleton<MiningRPCController>();
services.AddSingleton<MinerSettings>();
......
using Microsoft.Extensions.Logging;
using NBitcoin;
using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.Features.Consensus;
using Stratis.Bitcoin.Features.Consensus.Interfaces;
using Stratis.Bitcoin.Features.MemoryPool;
using Stratis.Bitcoin.Features.MemoryPool.Interfaces;
using Stratis.Bitcoin.Mining;
using Stratis.Bitcoin.Utilities;
namespace Stratis.Bitcoin.Features.Miner
{
/// <summary>
/// Defines how a proof of work block will be built on a proof of stake network.
/// </summary>
public sealed class PosPowBlockDefinition : BlockDefinition
{
/// <summary>Instance logger.</summary>
private readonly ILogger logger;
/// <summary>Database of stake related data for the current blockchain.</summary>
private readonly IStakeChain stakeChain;
/// <summary>Provides functionality for checking validity of PoS blocks.</summary>
private readonly IStakeValidator stakeValidator;
public PosPowBlockDefinition(
IConsensusLoop consensusLoop,
IDateTimeProvider dateTimeProvider,
ILoggerFactory loggerFactory,
ITxMempool mempool,
MempoolSchedulerLock mempoolLock,
Network network,
IStakeChain stakeChain,
IStakeValidator stakeValidator)
: base(consensusLoop, dateTimeProvider, loggerFactory, mempool, mempoolLock, network)
{
this.logger = loggerFactory.CreateLogger(this.GetType().FullName);
this.stakeChain = stakeChain;
this.stakeValidator = stakeValidator;
}
/// <inheritdoc/>
public override void AddToBlock(TxMempoolEntry mempoolEntry)
{
this.logger.LogTrace("({0}.{1}:'{2}', {3}:{4})", nameof(mempoolEntry), nameof(mempoolEntry.TransactionHash), mempoolEntry.TransactionHash, nameof(mempoolEntry.ModifiedFee), mempoolEntry.ModifiedFee);
this.AddTransactionToBlock(mempoolEntry.Transaction);
this.UpdateBlockStatistics(mempoolEntry);
this.UpdateTotalFees(mempoolEntry.Fee);
this.logger.LogTrace("(-)");
}
/// <inheritdoc/>
public override BlockTemplate Build(ChainedHeader chainTip, Script scriptPubKey)
{
this.logger.LogTrace("({0}:'{1}',{2}.{3}:{4})", nameof(chainTip), chainTip, nameof(scriptPubKey), nameof(scriptPubKey.Length), scriptPubKey.Length);
this.OnBuild(chainTip, scriptPubKey);
this.logger.LogTrace("(-)");
return this.BlockTemplate;
}
/// <inheritdoc/>
public override void UpdateHeaders()
{
this.logger.LogTrace("()");
base.UpdateBaseHeaders();
this.block.Header.Bits = this.stakeValidator.GetNextTargetRequired(this.stakeChain, this.ChainTip, this.Network.Consensus, false);
this.logger.LogTrace("(-)");
}
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Stratis Bitcoin Features Miner</Description>
<AssemblyTitle>Stratis.Bitcoin.Features.Miner</AssemblyTitle>
......@@ -17,18 +16,15 @@
<Version>1.1.12-beta</Version>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Stratis.Bitcoin.Features.Miner\**" />
<EmbeddedResource Remove="Stratis.Bitcoin.Features.Miner\**" />
<None Remove="Stratis.Bitcoin.Features.Miner\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NBitcoin\NBitcoin.csproj" />
<ProjectReference Include="..\Stratis.Bitcoin.Features.MemoryPool\Stratis.Bitcoin.Features.MemoryPool.csproj" />
......@@ -36,14 +32,12 @@
<ProjectReference Include="..\Stratis.Bitcoin.Features.Wallet\Stratis.Bitcoin.Features.Wallet.csproj" />
<ProjectReference Include="..\Stratis.Bitcoin\Stratis.Bitcoin.csproj" />
</ItemGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<DefineConstants>$(DefineConstants);NETCORE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702;1705;IDE0008;</NoWarn>
<DocumentationFile></DocumentationFile>
<DocumentationFile>
</DocumentationFile>
</PropertyGroup>
</Project>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment