From b83d16f6095159cf829a731177729f11db75da86 Mon Sep 17 00:00:00 2001
From: Dennis <41244965+DennisAMenace@users.noreply.github.com>
Date: Wed, 27 May 2020 19:19:41 -0600
Subject: [PATCH] Added blockmintxfee setting to BlockDefinitionOptions (#133)
* Added blockmintxfee setting to BlockDefinitionOptions
Added RewardRequired
Updated x42 consensus and added MinBlockFeeRate to consensus options.
* Updated x42 consensus.
* Added additional test node.
* Removed RewardRequired and changed the reward check logic.
---
src/External/NBitcoin/ConsensusOptions.cs | 4 ++++
.../BlockDefinitionOptions.cs | 5 +++--
.../Blockcore.Features.Miner/MinerSettings.cs | 6 +++++-
.../Blockcore.Features.Miner/PowMining.cs | 3 ---
.../Staking/PosMinting.cs | 2 +-
src/Networks/x42/x42/Networks/x42Main.cs | 3 ++-
src/Networks/x42/x42/Networks/x42Test.cs | 15 ++++++++++++++-
src/Networks/x42/x42/x42Setup.cs | 8 ++++----
.../Blockcore.IntegrationTests/MinerTests.cs | 6 ++----
9 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/src/External/NBitcoin/ConsensusOptions.cs b/src/External/NBitcoin/ConsensusOptions.cs
index eb7018a7c..2d87adb9c 100644
--- a/src/External/NBitcoin/ConsensusOptions.cs
+++ b/src/External/NBitcoin/ConsensusOptions.cs
@@ -19,6 +19,9 @@ public class ConsensusOptions
/// The maximum allowed weight for a block, see BIP 141 (network rule)
public uint MaxBlockWeight { get; set; }
+ /// Thee minimum feerate for a transaction in blocks mined.
+ public long MinBlockFeeRate { get; set; }
+
/// The maximum allowed size for a serialized block, in bytes (only for buffer size limits).
public uint MaxBlockSerializedSize { get; set; }
@@ -59,6 +62,7 @@ public ConsensusOptions()
// TODO: Remove this constructor. Should always set explicitly.
this.MaxBlockSerializedSize = 4000000;
this.MaxBlockWeight = 4000000;
+ this.MinBlockFeeRate = 1000;
this.WitnessScaleFactor = 4;
this.MaxStandardVersion = 2;
this.MaxStandardTxWeight = 400000;
diff --git a/src/Features/Blockcore.Features.Miner/BlockDefinitionOptions.cs b/src/Features/Blockcore.Features.Miner/BlockDefinitionOptions.cs
index 2385b8bd0..8d0cf43eb 100644
--- a/src/Features/Blockcore.Features.Miner/BlockDefinitionOptions.cs
+++ b/src/Features/Blockcore.Features.Miner/BlockDefinitionOptions.cs
@@ -20,11 +20,11 @@ public sealed class BlockDefinitionOptions
/// Minimum fee rate for transactions to be included in blocks created by miner.
public FeeRate BlockMinFeeRate { get; private set; }
- public BlockDefinitionOptions(uint blockMaxWeight, uint blockMaxSize)
+ public BlockDefinitionOptions(uint blockMaxWeight, uint blockMaxSize, int blockMinFeeRate)
{
this.BlockMaxWeight = blockMaxWeight;
this.BlockMaxSize = blockMaxSize;
- this.BlockMinFeeRate = new FeeRate(PowMining.DefaultBlockMinTxFee); // TODO: Where should this be set, really?
+ this.BlockMinFeeRate = new FeeRate(blockMinFeeRate);
}
///
@@ -36,6 +36,7 @@ public BlockDefinitionOptions RestrictForNetwork(Network network)
uint minAllowedBlockWeight = MinBlockSize * (uint) network.Consensus.Options.WitnessScaleFactor;
this.BlockMaxWeight = Math.Max(minAllowedBlockWeight, Math.Min(network.Consensus.Options.MaxBlockWeight, this.BlockMaxWeight));
this.BlockMaxSize = Math.Max(MinBlockSize, Math.Min(network.Consensus.Options.MaxBlockSerializedSize, this.BlockMaxSize));
+ this.BlockMinFeeRate = new FeeRate(Math.Max(network.Consensus.Options.MinBlockFeeRate, this.BlockMinFeeRate.FeePerK));
return this;
}
diff --git a/src/Features/Blockcore.Features.Miner/MinerSettings.cs b/src/Features/Blockcore.Features.Miner/MinerSettings.cs
index 8fc49a94a..c80631514 100644
--- a/src/Features/Blockcore.Features.Miner/MinerSettings.cs
+++ b/src/Features/Blockcore.Features.Miner/MinerSettings.cs
@@ -96,8 +96,9 @@ public MinerSettings(NodeSettings nodeSettings)
uint blockMaxSize = (uint) config.GetOrDefault("blockmaxsize", (int) nodeSettings.Network.Consensus.Options.MaxBlockSerializedSize, this.logger);
uint blockMaxWeight = (uint) config.GetOrDefault("blockmaxweight", (int) nodeSettings.Network.Consensus.Options.MaxBlockWeight, this.logger);
+ int blockmintxfee = config.GetOrDefault("blockmintxfee", (int)nodeSettings.Network.Consensus.Options.MinBlockFeeRate, this.logger);
- this.BlockDefinitionOptions = new BlockDefinitionOptions(blockMaxWeight, blockMaxSize).RestrictForNetwork(nodeSettings.Network);
+ this.BlockDefinitionOptions = new BlockDefinitionOptions(blockMaxWeight, blockMaxSize, blockmintxfee).RestrictForNetwork(nodeSettings.Network);
this.EnableCoinStakeSplitting = config.GetOrDefault("enablecoinstakesplitting", true, this.logger);
this.MinimumSplitCoinValue = config.GetOrDefault("minimumsplitcoinvalue", MinimumSplitCoinValueDefaultValue, this.logger);
@@ -123,6 +124,7 @@ public static void PrintHelp(Network network)
builder.AppendLine("-walletpassword= Password to unlock the wallet.");
builder.AppendLine("-blockmaxsize= Maximum block size (in bytes) for the miner to generate.");
builder.AppendLine("-blockmaxweight= Maximum block weight (in weight units) for the miner to generate.");
+ builder.AppendLine("-blockmintxfee= Minimum fee rate for transactions to be included in blocks created by miner.");
builder.AppendLine("-enablecoinstakesplitting=<0 or 1> Enable splitting coins when staking. This is true by default.");
builder.AppendLine($"-minimumstakingcoinvalue= Minimum size of the coins considered for staking, in satoshis. Default value is {MinimumStakingCoinValueDefaultValue:N0} satoshis (= {MinimumStakingCoinValueDefaultValue / (decimal)Money.COIN:N1} Coin).");
builder.AppendLine($"-minimumsplitcoinvalue= Targeted minimum value of staking coins after splitting, in satoshis. Default value is {MinimumSplitCoinValueDefaultValue:N0} satoshis (= {MinimumSplitCoinValueDefaultValue / Money.COIN} Coin).");
@@ -154,6 +156,8 @@ public static void BuildDefaultConfigurationFile(StringBuilder builder, Network
builder.AppendLine($"#blockmaxsize={network.Consensus.Options.MaxBlockSerializedSize}");
builder.AppendLine("#Maximum block weight (in weight units) for the miner to generate.");
builder.AppendLine($"#blockmaxweight={network.Consensus.Options.MaxBlockWeight}");
+ builder.AppendLine("#Minimum fee rate for transactions to be included in blocks created by miner.");
+ builder.AppendLine($"#blockmintxfee={network.Consensus.Options.MinBlockFeeRate}");
builder.AppendLine("#Enable splitting coins when staking.");
builder.AppendLine("#enablecoinstakesplitting=1");
builder.AppendLine("#Minimum size of the coins considered for staking, in satoshis.");
diff --git a/src/Features/Blockcore.Features.Miner/PowMining.cs b/src/Features/Blockcore.Features.Miner/PowMining.cs
index 911aea2aa..a0addc333 100644
--- a/src/Features/Blockcore.Features.Miner/PowMining.cs
+++ b/src/Features/Blockcore.Features.Miner/PowMining.cs
@@ -47,9 +47,6 @@ public class PowMining : IPowMining
/// Provider of time functions.
private readonly IDateTimeProvider dateTimeProvider;
- /// Default for "-blockmintxfee", which sets the minimum feerate for a transaction in blocks created by mining code.
- public const int DefaultBlockMinTxFee = 1000;
-
private uint256 hashPrevBlock;
private const int InnerLoopCount = 0x10000;
diff --git a/src/Features/Blockcore.Features.Miner/Staking/PosMinting.cs b/src/Features/Blockcore.Features.Miner/Staking/PosMinting.cs
index a0dcf8f28..f057cc43f 100644
--- a/src/Features/Blockcore.Features.Miner/Staking/PosMinting.cs
+++ b/src/Features/Blockcore.Features.Miner/Staking/PosMinting.cs
@@ -719,7 +719,7 @@ await Task.Run(() => Parallel.ForEach(workerContexts, cwc =>
// Get reward for newly created block.
long reward = fees + this.consensusManager.ConsensusRules.GetRule().GetProofOfStakeReward(chainTip.Height + 1);
- if (reward <= 0)
+ if (reward < 0)
{
// TODO: This can't happen unless we remove reward for mined block.
// If this can happen over time then this check could be done much sooner
diff --git a/src/Networks/x42/x42/Networks/x42Main.cs b/src/Networks/x42/x42/Networks/x42Main.cs
index 42d8ec133..b99446ea5 100644
--- a/src/Networks/x42/x42/Networks/x42Main.cs
+++ b/src/Networks/x42/x42/Networks/x42Main.cs
@@ -31,6 +31,7 @@ public x42Main()
maxStandardTxSigopsCost: 20_000 / 5,
witnessScaleFactor: 4
);
+ consensusOptions.MinBlockFeeRate = Money.Zero;
// END MODIFICATIONS
CoinSetup setup = x42Setup.Instance.Setup;
@@ -109,7 +110,7 @@ public x42Main()
minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
maxReorgLength: 500,
defaultAssumeValid: null,
- maxMoney: long.MaxValue,
+ maxMoney: Money.Coins(42 * 1000000),
coinbaseMaturity: 50,
premineHeight: 2,
premineReward: Money.Coins(setup.PremineReward),
diff --git a/src/Networks/x42/x42/Networks/x42Test.cs b/src/Networks/x42/x42/Networks/x42Test.cs
index edd0b5bd1..c5889c49f 100644
--- a/src/Networks/x42/x42/Networks/x42Test.cs
+++ b/src/Networks/x42/x42/Networks/x42Test.cs
@@ -8,6 +8,7 @@
using NBitcoin.BouncyCastle.Math;
using NBitcoin.DataEncoders;
using NBitcoin.Protocol;
+using x42.Networks.Deployments;
namespace x42.Networks
{
@@ -24,6 +25,7 @@ public x42Test()
maxStandardTxSigopsCost: 20_000 / 5,
witnessScaleFactor: 4
);
+ consensusOptions.MinBlockFeeRate = Money.Zero;
// END MODIFICATIONS
CoinSetup setup = x42Setup.Instance.Setup;
@@ -47,6 +49,10 @@ public x42Test()
this.DefaultAPIPort = network.DefaultAPIPort;
this.DefaultBanTimeSeconds = 288; // 9 (MaxReorg) * 64 (TargetSpacing) / 2 = 4 hours, 26 minutes and 40 seconds
+ this.MinTxFee = Money.Zero;
+ this.FallbackFee = Money.Zero;
+ this.MinRelayTxFee = Money.Zero;
+
var consensusFactory = new PosConsensusFactory();
// Create the genesis block.
@@ -73,6 +79,13 @@ public x42Test()
[BuriedDeployments.BIP66] = 0
};
+ var bip9Deployments = new x42BIP9Deployments
+ {
+ [x42BIP9Deployments.ColdStaking] = new BIP9DeploymentsParameters("ColdStaking", 27, BIP9DeploymentsParameters.AlwaysActive, 999999999, BIP9DeploymentsParameters.DefaultMainnetThreshold),
+ [x42BIP9Deployments.CSV] = new BIP9DeploymentsParameters("CSV", 0, BIP9DeploymentsParameters.AlwaysActive, 999999999, BIP9DeploymentsParameters.DefaultMainnetThreshold),
+ [x42BIP9Deployments.Segwit] = new BIP9DeploymentsParameters("Segwit", 1, new DateTime(2020, 3, 1, 0, 0, 0, DateTimeKind.Utc), new DateTime(2021, 3, 1, 0, 0, 0, DateTimeKind.Utc), BIP9DeploymentsParameters.DefaultMainnetThreshold)
+ };
+
consensusFactory.Protocol = new ConsensusProtocol()
{
ProtocolVersion = ProtocolVersion.FEEFILTER_VERSION,
@@ -89,7 +102,7 @@ public x42Test()
majorityRejectBlockOutdated: 950,
majorityWindow: 1000,
buriedDeployments: buriedDeployments,
- bip9Deployments: new NoBIP9Deployments(),
+ bip9Deployments: bip9Deployments,
bip34Hash: null,
minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
maxReorgLength: 9,
diff --git a/src/Networks/x42/x42/x42Setup.cs b/src/Networks/x42/x42/x42Setup.cs
index 7132b2f89..27d1654b7 100644
--- a/src/Networks/x42/x42/x42Setup.cs
+++ b/src/Networks/x42/x42/x42Setup.cs
@@ -25,7 +25,7 @@ internal class x42Setup
ProofOfStakeTimestampMask = 0x0000000F,
BlocksWithoutRewards = true,
LastProofOfStakeRewardHeight = 12155230,
- ProofOfStakeRewardAfterSubsidyLimit = 2,
+ ProofOfStakeRewardAfterSubsidyLimit = Money.Coins(2),
SubsidyLimit = 400000,
PoSVersion = 3
};
@@ -50,7 +50,7 @@ internal class x42Setup
HashGenesisBlock = "0x04ffe583707a96c1c2eb54af33a4b1dc6d9d8e09fea8c9a7b097ba88f0cb64c4",
HashMerkleRoot = "0x6e3439a32382f83dee4f94a6f8bdd38908bcf0c82ec09aba85c5321357f01f67",
DNS = new[] { "mainnet1.x42seed.host", "mainnetnode1.x42seed.host", "tech.x42.cloud", "x42.seed.blockcore.net" },
- Nodes = new[] { "34.255.35.42", "52.211.235.48", "63.32.82.169" },
+ Nodes = new[] { "34.255.35.42", "52.211.235.48", "63.32.82.169", "18.179.72.204", "15.188.129.215", "18.157.117.214" },
Checkpoints = new Dictionary
{
{ 0, new CheckpointInfo(new uint256("0x04ffe583707a96c1c2eb54af33a4b1dc6d9d8e09fea8c9a7b097ba88f0cb64c4"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) }, // Genisis
@@ -60,7 +60,7 @@ internal class x42Setup
{ 200000, new CheckpointInfo(new uint256("0xaa276a1c51c025ff1a21fd4b07bfa5d55effc173840e054dd851b20dbb1f2f17"), new uint256("0x63d4bc7b0272703e94ae79103970ea324dc85221e88a51c39a170744848c0cc7")) },
{ 300000, new CheckpointInfo(new uint256("0xff72e73ee8f87c0de9bf82c3bb758f4905c3e005493f2ed1faede7c120961750"), new uint256("0x2097fc9edfb8dfe287db45bbce820e168c50be32c9840b1cddf56b297011fc69")) },
{ 500000, new CheckpointInfo(new uint256("0x7f9a88ebb32f47090ec37a110c5a05c1162a604dfbfb69c8d492e771cdb63289"), new uint256("0x19db6890c5c934e883bc99eb197509b0a81f19faeefcf49fd7fa6dab83644bfb")) },
- { 634600, new CheckpointInfo(new uint256("0x5c0eb47bc96ba437e6d2550aceaa73ad9a4568110de83380d6a7b5f00aee7308"), new uint256("0x12ef7b665a07cef572c9b8d9ee44f41230d6a65e960d372f9396194ed6f51e53")) }
+ { 800000, new CheckpointInfo(new uint256("0x981083b047ecf8157a8b2dc24e17ca8cfad01b4e2dabc314df97f3b64fdf37f5"), new uint256("0xf3f0a821801b32c73a7c4f42416ddad3f74b732bd517c968a9b93a33d3684e0b")) }
}
};
@@ -111,7 +111,7 @@ internal class x42Setup
HashGenesisBlock = "0x11bd504102b42b24680d7b4f9b9e9521adc1b690253494d108193cdfcdd2ef0b",
HashMerkleRoot = "0x87e7f7df2fbe9fa56c627e59342e0d8142eb5e44c5e5769609059a60f17d0702",
DNS = new[] { "testnet1.x42seed.host" },
- Nodes = new[] { "63.32.82.169" },
+ Nodes = new[] { "63.32.82.169", "35.155.194.159" },
Checkpoints = new Dictionary
{
{ 0, new CheckpointInfo(new uint256("0x11bd504102b42b24680d7b4f9b9e9521adc1b690253494d108193cdfcdd2ef0b"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) }, // Genisis
diff --git a/src/Tests/Blockcore.IntegrationTests/MinerTests.cs b/src/Tests/Blockcore.IntegrationTests/MinerTests.cs
index 51db4085b..0e424510e 100644
--- a/src/Tests/Blockcore.IntegrationTests/MinerTests.cs
+++ b/src/Tests/Blockcore.IntegrationTests/MinerTests.cs
@@ -51,8 +51,6 @@ public class MinerTests
private readonly Network network;
- private static FeeRate blockMinFeeRate = new FeeRate(PowMining.DefaultBlockMinTxFee);
-
public static PowBlockDefinition AssemblerForTest(TestContext testContext)
{
return new PowBlockDefinition(testContext.consensus, testContext.DateTimeProvider, new LoggerFactory(), testContext.mempool, testContext.mempoolLock, new MinerSettings(NodeSettings.Default(testContext.network)), testContext.network, testContext.ConsensusRules, new NodeDeployments(testContext.network, testContext.ChainIndexer));
@@ -312,7 +310,7 @@ public async Task MinerTestPackageSelectionAsync()
// Calculate a fee on child transaction that will put the package just
// below the block min tx fee (assuming 1 child tx of the same size).
- Money feeToUse = blockMinFeeRate.GetFee(2 * freeTxSize) - 1;
+ Money feeToUse = new FeeRate(this.network.Consensus.Options.MinBlockFeeRate).GetFee(2 * freeTxSize) - 1;
tx = context.network.CreateTransaction(tx.ToBytes());
tx.Inputs[0].PrevOut.Hash = hashFreeTx;
@@ -354,7 +352,7 @@ public async Task MinerTestPackageSelectionAsync()
tx = context.network.CreateTransaction(tx.ToBytes());
tx.Inputs[0].PrevOut.Hash = hashFreeTx2;
tx.Outputs.RemoveAt(1);
- feeToUse = blockMinFeeRate.GetFee(freeTxSize);
+ feeToUse = new FeeRate(this.network.Consensus.Options.MinBlockFeeRate).GetFee(freeTxSize);
tx.Outputs[0].Value = 5000000000L - 100000000 - feeToUse;
uint256 hashLowFeeTx2 = tx.GetHash();
context.mempool.AddUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx));