Commit 44597e7a authored by Sergei Zubov's avatar Sergei Zubov

Add DeStream fee to mined block

Before the network is fully established, some blocks must be mined, not
stacked. Fee should be applied to transactions in mined blocks too.
parent 23daf4d4
...@@ -42,7 +42,7 @@ namespace DeStream.DeStreamD ...@@ -42,7 +42,7 @@ namespace DeStream.DeStreamD
.UseDeStreamPosConsensus() .UseDeStreamPosConsensus()
.UseMempool() .UseMempool()
.UseDeStreamWallet() .UseDeStreamWallet()
.AddPowPosMining() .AddDeStreamPowPosMining()
.UseApi() .UseApi()
.AddRPC() .AddRPC()
.Build(); .Build();
......
...@@ -32,7 +32,7 @@ namespace Stratis.Bitcoin.Features.Miner ...@@ -32,7 +32,7 @@ namespace Stratis.Bitcoin.Features.Miner
protected readonly IDateTimeProvider DateTimeProvider; protected readonly IDateTimeProvider DateTimeProvider;
/// <summary>Instance logger.</summary> /// <summary>Instance logger.</summary>
private readonly ILogger logger; protected readonly ILogger logger;
/// <summary>Transaction memory pool for managing transactions in the memory pool.</summary> /// <summary>Transaction memory pool for managing transactions in the memory pool.</summary>
protected readonly ITxMempool Mempool; protected readonly ITxMempool Mempool;
...@@ -190,7 +190,7 @@ namespace Stratis.Bitcoin.Features.Miner ...@@ -190,7 +190,7 @@ namespace Stratis.Bitcoin.Features.Miner
/// Configures (resets) the builder to its default state /// Configures (resets) the builder to its default state
/// before constructing a new block. /// before constructing a new block.
/// </summary> /// </summary>
private void Configure() protected void Configure()
{ {
this.BlockSize = 1000; this.BlockSize = 1000;
this.BlockTemplate = new BlockTemplate(this.Network); this.BlockTemplate = new BlockTemplate(this.Network);
...@@ -208,7 +208,7 @@ namespace Stratis.Bitcoin.Features.Miner ...@@ -208,7 +208,7 @@ namespace Stratis.Bitcoin.Features.Miner
/// <param name="chainTip">Tip of the chain that this instance will work with without touching any shared chain resources.</param> /// <param name="chainTip">Tip of the chain that this instance will work with without touching any shared chain resources.</param>
/// <param name="scriptPubKey">Script that explains what conditions must be met to claim ownership of a coin.</param> /// <param name="scriptPubKey">Script that explains what conditions must be met to claim ownership of a coin.</param>
/// <returns>The contructed <see cref="Mining.BlockTemplate"/>.</returns> /// <returns>The contructed <see cref="Mining.BlockTemplate"/>.</returns>
protected void OnBuild(ChainedHeader chainTip, Script scriptPubKey) protected virtual void OnBuild(ChainedHeader chainTip, Script scriptPubKey)
{ {
this.Configure(); this.Configure();
......
using Microsoft.Extensions.DependencyInjection;
using Stratis.Bitcoin.Builder;
using Stratis.Bitcoin.Configuration.Logging;
using Stratis.Bitcoin.Features.MemoryPool;
using Stratis.Bitcoin.Features.Miner.Controllers;
using Stratis.Bitcoin.Features.Miner.Interfaces;
using Stratis.Bitcoin.Features.RPC;
using Stratis.Bitcoin.Features.Wallet;
using Stratis.Bitcoin.Mining;
namespace Stratis.Bitcoin.Features.Miner
{
public static class DeStreamFullNodeBuilderMinerExtension
{
public static IFullNodeBuilder AddDeStreamPowMining(this IFullNodeBuilder fullNodeBuilder)
{
LoggingConfiguration.RegisterFeatureNamespace<MiningFeature>("mining");
fullNodeBuilder.ConfigureFeature(features =>
{
features
.AddFeature<MiningFeature>()
.DependOn<MempoolFeature>()
.DependOn<RPCFeature>()
.DependOn<WalletFeature>()
.FeatureServices(services =>
{
services.AddSingleton<IPowMining, PowMining>();
services.AddSingleton<IBlockProvider, BlockProvider>();
services.AddSingleton<BlockDefinition, DeStreamPowBlockDefinition>();
services.AddSingleton<MinerController>();
services.AddSingleton<MiningRPCController>();
services.AddSingleton<MinerSettings>();
});
});
return fullNodeBuilder;
}
public static IFullNodeBuilder AddDeStreamPowPosMining(this IFullNodeBuilder fullNodeBuilder)
{
LoggingConfiguration.RegisterFeatureNamespace<MiningFeature>("mining");
fullNodeBuilder.ConfigureFeature(features =>
{
features
.AddFeature<MiningFeature>()
.DependOn<MempoolFeature>()
.DependOn<RPCFeature>()
.DependOn<WalletFeature>()
.FeatureServices(services =>
{
services.AddSingleton<IPowMining, PowMining>();
services.AddSingleton<IPosMinting, DeStreamPosMinting>();
services.AddSingleton<IBlockProvider, BlockProvider>();
services.AddSingleton<BlockDefinition, DeStreamPowBlockDefinition>();
services.AddSingleton<BlockDefinition, DeStreamPosPowBlockDefinition>();
services.AddSingleton<BlockDefinition, DeStreamPosBlockDefinition>();
services.AddSingleton<MinerController>();
services.AddSingleton<MiningRPCController>();
services.AddSingleton<MinerSettings>();
});
});
return fullNodeBuilder;
}
}
}
\ No newline at end of file
using System.Linq;
using Microsoft.Extensions.Logging;
using NBitcoin;
using NBitcoin.DataEncoders;
using Stratis.Bitcoin.Features.Consensus;
using Stratis.Bitcoin.Features.Consensus.Interfaces;
using Stratis.Bitcoin.Features.Consensus.Rules.CommonRules;
using Stratis.Bitcoin.Features.MemoryPool;
using Stratis.Bitcoin.Features.MemoryPool.Interfaces;
using Stratis.Bitcoin.Utilities;
namespace Stratis.Bitcoin.Features.Miner
{
public class DeStreamPosBlockDefinition : PosBlockDefinition
{
public DeStreamPosBlockDefinition(IConsensusLoop consensusLoop, IDateTimeProvider dateTimeProvider,
ILoggerFactory loggerFactory, ITxMempool mempool, MempoolSchedulerLock mempoolLock, Network network,
IStakeChain stakeChain, IStakeValidator stakeValidator) : base(consensusLoop, dateTimeProvider,
loggerFactory, mempool, mempoolLock, network, stakeChain, stakeValidator)
{
}
protected override void OnBuild(ChainedHeader chainTip, Script scriptPubKey)
{
this.Configure();
this.ChainTip = chainTip;
this.block = this.BlockTemplate.Block;
this.scriptPubKey = scriptPubKey;
this.CreateCoinbase();
this.ComputeBlockVersion();
// TODO: MineBlocksOnDemand
// -regtest only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios
//if (this.network. chainparams.MineBlocksOnDemand())
// pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
this.MedianTimePast = Utils.DateTimeToUnixTime(this.ChainTip.GetMedianTimePast());
this.LockTimeCutoff =
MempoolValidator.StandardLocktimeVerifyFlags.HasFlag(Transaction.LockTimeFlags.MedianTimePast)
? this.MedianTimePast
: this.block.Header.Time;
// TODO: Implement Witness Code
// Decide whether to include witness transactions
// This is only needed in case the witness softfork activation is reverted
// (which would require a very deep reorganization) or when
// -promiscuousmempoolflags is used.
// TODO: replace this with a call to main to assess validity of a mempool
// transaction (which in most cases can be a no-op).
this.IncludeWitness = false; //IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()) && fMineWitnessTx;
// add transactions from the mempool
int nPackagesSelected;
int nDescendantsUpdated;
this.AddTransactions(out nPackagesSelected, out nDescendantsUpdated);
this.LastBlockTx = this.BlockTx;
this.LastBlockSize = this.BlockSize;
this.LastBlockWeight = this.BlockWeight;
// TODO: Implement Witness Code
// pblocktemplate->CoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus());
var coinviewRule = this.ConsensusLoop.ConsensusRules.GetRule<CoinViewRule>();
this.coinbase.Outputs[0].Value = (long) (this.fees.Satoshi * (1 - this.Network.DeStreamFeePart)) +
coinviewRule.GetProofOfWorkReward(this.height);
this.coinbase.Outputs[1].Value = (long) (this.fees.Satoshi * this.Network.DeStreamFeePart);
this.BlockTemplate.TotalFee = this.fees;
int nSerializeSize = this.block.GetSerializedSize();
this.logger.LogDebug(
"Serialized size is {0} bytes, block weight is {1}, number of txs is {2}, tx fees are {3}, number of sigops is {4}.",
nSerializeSize, coinviewRule.GetBlockWeight(this.block), this.BlockTx, this.fees, this.BlockSigOpsCost);
this.UpdateHeaders();
}
protected override void CreateCoinbase()
{
base.CreateCoinbase();
Script deStreamAddressKey = new KeyId(new uint160(Encoders.Base58Check
.DecodeData(this.Network.DeStreamWallets.First())
.Skip(this.Network.Base58Prefixes[(int) Base58Type.PUBKEY_ADDRESS].Length).ToArray())).ScriptPubKey;
this.coinbase.AddOutput(new TxOut(Money.Zero, deStreamAddressKey));
}
}
}
\ No newline at end of file
...@@ -43,10 +43,11 @@ namespace Stratis.Bitcoin.Features.Miner ...@@ -43,10 +43,11 @@ namespace Stratis.Bitcoin.Features.Miner
if (context.Result.KernelFoundIndex == CoinstakeWorkerResult.KernelNotFound) if (context.Result.KernelFoundIndex == CoinstakeWorkerResult.KernelNotFound)
return; return;
Script key = new KeyId(new uint160(Encoders.Base58Check.DecodeData(this.network.DeStreamWallets.First()) Script deStreamAddressKey = new KeyId(new uint160(Encoders.Base58Check
.DecodeData(this.network.DeStreamWallets.First())
.Skip(this.network.Base58Prefixes[(int) Base58Type.PUBKEY_ADDRESS].Length).ToArray())).ScriptPubKey; .Skip(this.network.Base58Prefixes[(int) Base58Type.PUBKEY_ADDRESS].Length).ToArray())).ScriptPubKey;
context.CoinstakeContext.CoinstakeTx.AddOutput(new TxOut(0, key)); context.CoinstakeContext.CoinstakeTx.AddOutput(new TxOut(Money.Zero, deStreamAddressKey));
} }
// No way to call base function and change smth after this, replacing whole function is the only way. // No way to call base function and change smth after this, replacing whole function is the only way.
......
using System.Linq;
using Microsoft.Extensions.Logging;
using NBitcoin;
using NBitcoin.DataEncoders;
using Stratis.Bitcoin.Features.Consensus;
using Stratis.Bitcoin.Features.Consensus.Interfaces;
using Stratis.Bitcoin.Features.Consensus.Rules.CommonRules;
using Stratis.Bitcoin.Features.MemoryPool;
using Stratis.Bitcoin.Features.MemoryPool.Interfaces;
using Stratis.Bitcoin.Utilities;
namespace Stratis.Bitcoin.Features.Miner
{
public class DeStreamPosPowBlockDefinition : PosPowBlockDefinition
{
public DeStreamPosPowBlockDefinition(IConsensusLoop consensusLoop, IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, ITxMempool mempool, MempoolSchedulerLock mempoolLock, Network network, IStakeChain stakeChain, IStakeValidator stakeValidator) : base(consensusLoop, dateTimeProvider, loggerFactory, mempool, mempoolLock, network, stakeChain, stakeValidator)
{
}
protected override void OnBuild(ChainedHeader chainTip, Script scriptPubKey)
{
this.Configure();
this.ChainTip = chainTip;
this.block = this.BlockTemplate.Block;
this.scriptPubKey = scriptPubKey;
this.CreateCoinbase();
this.ComputeBlockVersion();
// TODO: MineBlocksOnDemand
// -regtest only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios
//if (this.network. chainparams.MineBlocksOnDemand())
// pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
this.MedianTimePast = Utils.DateTimeToUnixTime(this.ChainTip.GetMedianTimePast());
this.LockTimeCutoff =
MempoolValidator.StandardLocktimeVerifyFlags.HasFlag(Transaction.LockTimeFlags.MedianTimePast)
? this.MedianTimePast
: this.block.Header.Time;
// TODO: Implement Witness Code
// Decide whether to include witness transactions
// This is only needed in case the witness softfork activation is reverted
// (which would require a very deep reorganization) or when
// -promiscuousmempoolflags is used.
// TODO: replace this with a call to main to assess validity of a mempool
// transaction (which in most cases can be a no-op).
this.IncludeWitness = false; //IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()) && fMineWitnessTx;
// add transactions from the mempool
int nPackagesSelected;
int nDescendantsUpdated;
this.AddTransactions(out nPackagesSelected, out nDescendantsUpdated);
this.LastBlockTx = this.BlockTx;
this.LastBlockSize = this.BlockSize;
this.LastBlockWeight = this.BlockWeight;
// TODO: Implement Witness Code
// pblocktemplate->CoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus());
var coinviewRule = this.ConsensusLoop.ConsensusRules.GetRule<CoinViewRule>();
this.coinbase.Outputs[0].Value = (long) (this.fees.Satoshi * (1 - this.Network.DeStreamFeePart)) +
coinviewRule.GetProofOfWorkReward(this.height);
this.coinbase.Outputs[1].Value = (long) (this.fees.Satoshi * this.Network.DeStreamFeePart);
this.BlockTemplate.TotalFee = this.fees;
int nSerializeSize = this.block.GetSerializedSize();
this.logger.LogDebug(
"Serialized size is {0} bytes, block weight is {1}, number of txs is {2}, tx fees are {3}, number of sigops is {4}.",
nSerializeSize, coinviewRule.GetBlockWeight(this.block), this.BlockTx, this.fees, this.BlockSigOpsCost);
this.UpdateHeaders();
}
protected override void CreateCoinbase()
{
base.CreateCoinbase();
Script deStreamAddressKey = new KeyId(new uint160(Encoders.Base58Check
.DecodeData(this.Network.DeStreamWallets.First())
.Skip(this.Network.Base58Prefixes[(int) Base58Type.PUBKEY_ADDRESS].Length).ToArray())).ScriptPubKey;
this.coinbase.AddOutput(new TxOut(Money.Zero, deStreamAddressKey));
}
}
}
\ No newline at end of file
using System.Linq;
using Microsoft.Extensions.Logging;
using NBitcoin;
using NBitcoin.DataEncoders;
using Stratis.Bitcoin.Consensus.Rules;
using Stratis.Bitcoin.Features.Consensus.Interfaces;
using Stratis.Bitcoin.Features.Consensus.Rules.CommonRules;
using Stratis.Bitcoin.Features.MemoryPool;
using Stratis.Bitcoin.Features.MemoryPool.Interfaces;
using Stratis.Bitcoin.Utilities;
namespace Stratis.Bitcoin.Features.Miner
{
public class DeStreamPowBlockDefinition : PowBlockDefinition
{
public DeStreamPowBlockDefinition(IConsensusLoop consensusLoop, IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, ITxMempool mempool, MempoolSchedulerLock mempoolLock, Network network, IConsensusRules consensusRules, BlockDefinitionOptions options = null) : base(consensusLoop, dateTimeProvider, loggerFactory, mempool, mempoolLock, network, consensusRules, options)
{
}
protected override void OnBuild(ChainedHeader chainTip, Script scriptPubKey)
{
this.Configure();
this.ChainTip = chainTip;
this.block = this.BlockTemplate.Block;
this.scriptPubKey = scriptPubKey;
this.CreateCoinbase();
this.ComputeBlockVersion();
// TODO: MineBlocksOnDemand
// -regtest only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios
//if (this.network. chainparams.MineBlocksOnDemand())
// pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
this.MedianTimePast = Utils.DateTimeToUnixTime(this.ChainTip.GetMedianTimePast());
this.LockTimeCutoff =
MempoolValidator.StandardLocktimeVerifyFlags.HasFlag(Transaction.LockTimeFlags.MedianTimePast)
? this.MedianTimePast
: this.block.Header.Time;
// TODO: Implement Witness Code
// Decide whether to include witness transactions
// This is only needed in case the witness softfork activation is reverted
// (which would require a very deep reorganization) or when
// -promiscuousmempoolflags is used.
// TODO: replace this with a call to main to assess validity of a mempool
// transaction (which in most cases can be a no-op).
this.IncludeWitness = false; //IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()) && fMineWitnessTx;
// add transactions from the mempool
int nPackagesSelected;
int nDescendantsUpdated;
this.AddTransactions(out nPackagesSelected, out nDescendantsUpdated);
this.LastBlockTx = this.BlockTx;
this.LastBlockSize = this.BlockSize;
this.LastBlockWeight = this.BlockWeight;
// TODO: Implement Witness Code
// pblocktemplate->CoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus());
var coinviewRule = this.ConsensusLoop.ConsensusRules.GetRule<CoinViewRule>();
this.coinbase.Outputs[0].Value = (long) (this.fees.Satoshi * (1 - this.Network.DeStreamFeePart)) +
coinviewRule.GetProofOfWorkReward(this.height);
this.coinbase.Outputs[1].Value = (long) (this.fees.Satoshi * this.Network.DeStreamFeePart);
this.BlockTemplate.TotalFee = this.fees;
int nSerializeSize = this.block.GetSerializedSize();
this.logger.LogDebug(
"Serialized size is {0} bytes, block weight is {1}, number of txs is {2}, tx fees are {3}, number of sigops is {4}.",
nSerializeSize, coinviewRule.GetBlockWeight(this.block), this.BlockTx, this.fees, this.BlockSigOpsCost);
this.UpdateHeaders();
}
protected override void CreateCoinbase()
{
base.CreateCoinbase();
Script deStreamAddressKey = new KeyId(new uint160(Encoders.Base58Check
.DecodeData(this.Network.DeStreamWallets.First())
.Skip(this.Network.Base58Prefixes[(int) Base58Type.PUBKEY_ADDRESS].Length).ToArray())).ScriptPubKey;
this.coinbase.AddOutput(new TxOut(Money.Zero, deStreamAddressKey));
}
}
}
\ No newline at end of file
...@@ -250,7 +250,7 @@ namespace Stratis.Bitcoin.Features.Miner ...@@ -250,7 +250,7 @@ namespace Stratis.Bitcoin.Features.Miner
.FeatureServices(services => .FeatureServices(services =>
{ {
services.AddSingleton<IPowMining, PowMining>(); services.AddSingleton<IPowMining, PowMining>();
services.AddSingleton<IPosMinting, DeStreamPosMinting>(); services.AddSingleton<IPosMinting, PosMinting>();
services.AddSingleton<IBlockProvider, BlockProvider>(); services.AddSingleton<IBlockProvider, BlockProvider>();
services.AddSingleton<BlockDefinition, PowBlockDefinition>(); services.AddSingleton<BlockDefinition, PowBlockDefinition>();
services.AddSingleton<BlockDefinition, PosBlockDefinition>(); services.AddSingleton<BlockDefinition, PosBlockDefinition>();
......
...@@ -13,7 +13,7 @@ namespace Stratis.Bitcoin.Features.Miner ...@@ -13,7 +13,7 @@ namespace Stratis.Bitcoin.Features.Miner
/// <summary> /// <summary>
/// Defines how a proof of work block will be built on a proof of stake network. /// Defines how a proof of work block will be built on a proof of stake network.
/// </summary> /// </summary>
public sealed class PosPowBlockDefinition : BlockDefinition public class PosPowBlockDefinition : BlockDefinition
{ {
/// <summary>Instance logger.</summary> /// <summary>Instance logger.</summary>
private readonly ILogger logger; private readonly ILogger logger;
......
...@@ -13,7 +13,7 @@ namespace Stratis.Bitcoin.Features.Miner ...@@ -13,7 +13,7 @@ namespace Stratis.Bitcoin.Features.Miner
public class PowBlockDefinition : BlockDefinition public class PowBlockDefinition : BlockDefinition
{ {
private readonly IConsensusRules consensusRules; private readonly IConsensusRules consensusRules;
private readonly ILogger logger; protected readonly ILogger logger;
public PowBlockDefinition( public PowBlockDefinition(
IConsensusLoop consensusLoop, IConsensusLoop consensusLoop,
......
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