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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using System.Text;
using NBitcoin.BouncyCastle.Math;
using NBitcoin.DataEncoders;
using NBitcoin.Protocol; using NBitcoin.Protocol;
namespace NBitcoin.Networks namespace NBitcoin.Networks
...@@ -12,8 +9,9 @@ namespace NBitcoin.Networks ...@@ -12,8 +9,9 @@ namespace NBitcoin.Networks
{ {
public DeStreamTest() //: base() public DeStreamTest() //: base()
{ {
string InitialWalletAddress = "TPPL2wmtxGzP8U6hQsGkRA9yCMsazB33ft"; const string initialWalletAddress = "TAE5v2wDwkrCPTDN51ru4YSZ8KvnFFrUQc";
decimal InitialCoins = 6000000000; const decimal initialCoins = 6000000000;
const int numberOfEmissionTransactions = 6;
// The message start string is designed to be unlikely to occur in normal data. // 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 // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
...@@ -31,27 +29,29 @@ namespace NBitcoin.Networks ...@@ -31,27 +29,29 @@ namespace NBitcoin.Networks
this.RPCPort = 0xDE10; // 56848, this.RPCPort = 0xDE10; // 56848,
this.CoinTicker = "TDST"; this.CoinTicker = "TDST";
this.Consensus.PowLimit = new Target(new uint256("0000ffff00000000000000000000000000000000000000000000000000000000")); this.Consensus.PowLimit =
this.Consensus.DefaultAssumeValid = new uint256("0x98fa6ef0bca5b431f15fd79dc6f879dc45b83ed4b1bbe933a383ef438321958e"); // 372652 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.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.PUBKEY_ADDRESS] = new byte[] {65};
this.Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS] = new byte[] { (196) }; this.Base58Prefixes[(int) Base58Type.SCRIPT_ADDRESS] = new byte[] {196};
this.Base58Prefixes[(int)Base58Type.SECRET_KEY] = new byte[] { (65 + 128) }; this.Base58Prefixes[(int) Base58Type.SECRET_KEY] = new byte[] {65 + 128};
this.Checkpoints = new Dictionary<int, CheckpointInfo> this.Checkpoints = new Dictionary<int, CheckpointInfo>();
{ // TODO: Add genesis and premine block to Checkpoints
{ 0, new CheckpointInfo(new uint256("0x00000e246d7b73b88c9ab55f2e5e94d9e22d471def3df5ea448f5576b1d156b9"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) }, // First parameter - block height
{ 2, new CheckpointInfo(new uint256("0x56959b1c8498631fb0ca5fe7bd83319dccdc6ac003dccb3171f39f553ecfa2f2"), new uint256("0x13f4c27ca813aefe2d9018077f8efeb3766796b9144fcc4cd51803bf4376ab02")) }, // { 0, new CheckpointInfo(new uint256("0x00000e246d7b73b88c9ab55f2e5e94d9e22d471def3df5ea448f5576b1d156b9"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) },
{ 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.DNSSeeds = new List<DNSSeedData> this.DNSSeeds = new List<DNSSeedData>
{ {
...@@ -69,17 +69,19 @@ namespace NBitcoin.Networks ...@@ -69,17 +69,19 @@ namespace NBitcoin.Networks
this.GenesisNonce = 1831645; this.GenesisNonce = 1831645;
this.GenesisBits = 0x1e0fffff; this.GenesisBits = 0x1e0fffff;
this.GenesisVersion = 1; this.GenesisVersion = 1;
this.GenesisReward = Money.Coins(InitialCoins); this.GenesisReward = Money.Coins(initialCoins);
this.GenesisWalletAddress = InitialWalletAddress; this.GenesisWalletAddress = initialWalletAddress;
this.Genesis = CreateDeStreamGenesisBlock(this.Consensus.ConsensusFactory, this.GenesisTime, this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward, this.GenesisWalletAddress); this.Genesis = this.CreateDeStreamGenesisBlock(this.Consensus.ConsensusFactory, this.GenesisTime,
this.Genesis.Header.Time = 1493909211; 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.Nonce = 2433759;
this.Genesis.Header.Bits = this.Consensus.PowLimit; this.Genesis.Header.Bits = this.Consensus.PowLimit;
this.Consensus.HashGenesisBlock = this.Genesis.GetHash(); this.Consensus.HashGenesisBlock = this.Genesis.GetHash();
// Assert(this.Consensus.HashGenesisBlock == uint256.Parse("c5974b227ccb19ebd97578285a5937bb4bfb6dcdbf473966d8a2f9c714a8dbb0")); // Assert(this.Consensus.HashGenesisBlock == uint256.Parse("c5974b227ccb19ebd97578285a5937bb4bfb6dcdbf473966d8a2f9c714a8dbb0"));
// Assert(this.Genesis.Header.HashMerkleRoot == uint256.Parse("9e3fff58fb1ba15a69198e22d99572fa024afb754bfe1d3b8d28b86fd9de62df")); // Assert(this.Genesis.Header.HashMerkleRoot == uint256.Parse("9e3fff58fb1ba15a69198e22d99572fa024afb754bfe1d3b8d28b86fd9de62df"));
} }
} }
} }
\ No newline at end of file
...@@ -8,17 +8,24 @@ namespace Stratis.Bitcoin.Features.Miner ...@@ -8,17 +8,24 @@ namespace Stratis.Bitcoin.Features.Miner
/// <inheritdoc/> /// <inheritdoc/>
public sealed class BlockProvider : IBlockProvider public sealed class BlockProvider : IBlockProvider
{ {
private readonly Network network;
/// <summary>Defines how proof of work blocks are built.</summary> /// <summary>Defines how proof of work blocks are built.</summary>
private readonly PowBlockDefinition powBlockDefinition; private readonly PowBlockDefinition powBlockDefinition;
/// <summary>Defines how proof of stake blocks are built.</summary> /// <summary>Defines how proof of stake blocks are built.</summary>
private readonly PosBlockDefinition posBlockDefinition; 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> /// <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.powBlockDefinition = definitions.OfType<PowBlockDefinition>().FirstOrDefault();
this.posBlockDefinition = definitions.OfType<PosBlockDefinition>().FirstOrDefault(); this.posBlockDefinition = definitions.OfType<PosBlockDefinition>().FirstOrDefault();
this.posPowBlockDefinition = definitions.OfType<PosPowBlockDefinition>().FirstOrDefault();
} }
/// <inheritdoc/> /// <inheritdoc/>
...@@ -30,6 +37,9 @@ namespace Stratis.Bitcoin.Features.Miner ...@@ -30,6 +37,9 @@ namespace Stratis.Bitcoin.Features.Miner
/// <inheritdoc/> /// <inheritdoc/>
public BlockTemplate BuildPowBlock(ChainedHeader chainTip, Script script) public BlockTemplate BuildPowBlock(ChainedHeader chainTip, Script script)
{ {
if (this.network.Consensus.IsProofOfStake)
return this.posPowBlockDefinition.Build(chainTip, script);
return this.powBlockDefinition.Build(chainTip, script); return this.powBlockDefinition.Build(chainTip, script);
} }
} }
......
...@@ -9,19 +9,19 @@ namespace Stratis.Bitcoin.Features.Miner.Interfaces ...@@ -9,19 +9,19 @@ namespace Stratis.Bitcoin.Features.Miner.Interfaces
/// Generates up to a specified number of blocks with a limited number of attempts. /// Generates up to a specified number of blocks with a limited number of attempts.
/// </summary> /// </summary>
/// <param name="reserveScript">The reserve script.</param> /// <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> /// <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> /// <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> /// <summary>
/// Increments or resets the extra nonce based on the previous hash block value on on the pow miner and the passed nExtraNonce. /// Increments or resets the extra nonce based on the previous hash block value on on the pow miner and the passed nExtraNonce.
/// </summary> /// </summary>
/// <param name="pblock">The template block.</param> /// <param name="block">The template block.</param>
/// <param name="pindexPrev">The previous chained block.</param> /// <param name="previousHeader">The previous chained block.</param>
/// <param name="nExtraNonce">The extra nonce counter.</param> /// <param name="extraNonce">The extra nonce counter.</param>
/// <returns>The new extra nonce after incrementing.</returns> /// <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> /// <summary>
/// Starts a new async mining loop or returns the existing running mining loop. /// Starts a new async mining loop or returns the existing running mining loop.
......
...@@ -254,6 +254,7 @@ namespace Stratis.Bitcoin.Features.Miner ...@@ -254,6 +254,7 @@ namespace Stratis.Bitcoin.Features.Miner
services.AddSingleton<IBlockProvider, BlockProvider>(); services.AddSingleton<IBlockProvider, BlockProvider>();
services.AddSingleton<BlockDefinition, PowBlockDefinition>(); services.AddSingleton<BlockDefinition, PowBlockDefinition>();
services.AddSingleton<BlockDefinition, PosBlockDefinition>(); services.AddSingleton<BlockDefinition, PosBlockDefinition>();
services.AddSingleton<BlockDefinition, PosPowBlockDefinition>();
services.AddSingleton<MinerController>(); services.AddSingleton<MinerController>();
services.AddSingleton<MiningRPCController>(); services.AddSingleton<MiningRPCController>();
services.AddSingleton<MinerSettings>(); 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"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Description>Stratis Bitcoin Features Miner</Description> <Description>Stratis Bitcoin Features Miner</Description>
<AssemblyTitle>Stratis.Bitcoin.Features.Miner</AssemblyTitle> <AssemblyTitle>Stratis.Bitcoin.Features.Miner</AssemblyTitle>
...@@ -17,18 +16,15 @@ ...@@ -17,18 +16,15 @@
<Version>1.1.12-beta</Version> <Version>1.1.12-beta</Version>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild> <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="Stratis.Bitcoin.Features.Miner\**" /> <Compile Remove="Stratis.Bitcoin.Features.Miner\**" />
<EmbeddedResource Remove="Stratis.Bitcoin.Features.Miner\**" /> <EmbeddedResource Remove="Stratis.Bitcoin.Features.Miner\**" />
<None Remove="Stratis.Bitcoin.Features.Miner\**" /> <None Remove="Stratis.Bitcoin.Features.Miner\**" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\NBitcoin\NBitcoin.csproj" /> <ProjectReference Include="..\NBitcoin\NBitcoin.csproj" />
<ProjectReference Include="..\Stratis.Bitcoin.Features.MemoryPool\Stratis.Bitcoin.Features.MemoryPool.csproj" /> <ProjectReference Include="..\Stratis.Bitcoin.Features.MemoryPool\Stratis.Bitcoin.Features.MemoryPool.csproj" />
...@@ -36,14 +32,12 @@ ...@@ -36,14 +32,12 @@
<ProjectReference Include="..\Stratis.Bitcoin.Features.Wallet\Stratis.Bitcoin.Features.Wallet.csproj" /> <ProjectReference Include="..\Stratis.Bitcoin.Features.Wallet\Stratis.Bitcoin.Features.Wallet.csproj" />
<ProjectReference Include="..\Stratis.Bitcoin\Stratis.Bitcoin.csproj" /> <ProjectReference Include="..\Stratis.Bitcoin\Stratis.Bitcoin.csproj" />
</ItemGroup> </ItemGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' "> <PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<DefineConstants>$(DefineConstants);NETCORE</DefineConstants> <DefineConstants>$(DefineConstants);NETCORE</DefineConstants>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702;1705;IDE0008;</NoWarn> <NoWarn>1701;1702;1705;IDE0008;</NoWarn>
<DocumentationFile></DocumentationFile> <DocumentationFile>
</DocumentationFile>
</PropertyGroup> </PropertyGroup>
</Project> </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