Commit 775402e3 authored by Sergei Zubov's avatar Sergei Zubov

Merge block fee rule

parent fbf32102
...@@ -118,7 +118,8 @@ namespace Stratis.Bitcoin.Features.Consensus ...@@ -118,7 +118,8 @@ namespace Stratis.Bitcoin.Features.Consensus
new LoadCoinviewRule(), new LoadCoinviewRule(),
new TransactionDuplicationActivationRule(), // implements BIP30 new TransactionDuplicationActivationRule(), // implements BIP30
new DeStreamPowCoinviewRule(), // implements BIP68, MaxSigOps and BlockReward calculation new DeStreamPowCoinviewRule(), // implements BIP68, MaxSigOps and BlockReward calculation
new SaveCoinviewRule() new SaveCoinviewRule(),
new DeStreamBlockFeeRule()
}; };
} }
} }
...@@ -178,7 +179,8 @@ namespace Stratis.Bitcoin.Features.Consensus ...@@ -178,7 +179,8 @@ namespace Stratis.Bitcoin.Features.Consensus
// Place the PosColdStakingRule after the PosCoinviewRule to ensure that all input scripts have been evaluated // Place the PosColdStakingRule after the PosCoinviewRule to ensure that all input scripts have been evaluated
// and that the "IsColdCoinStake" flag would have been set by the OP_CHECKCOLDSTAKEVERIFY opcode if applicable. // and that the "IsColdCoinStake" flag would have been set by the OP_CHECKCOLDSTAKEVERIFY opcode if applicable.
new PosColdStakingRule(), new PosColdStakingRule(),
new SaveCoinviewRule() new SaveCoinviewRule(),
new DeStreamBlockFeeRule()
}; };
} }
} }
......
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using NBitcoin; using NBitcoin;
using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.Consensus.Rules; using Stratis.Bitcoin.Consensus.Rules;
namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules
...@@ -10,32 +11,41 @@ namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules ...@@ -10,32 +11,41 @@ namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules
/// <summary> /// <summary>
/// A rule that verifies fee is charged from all spent funds and transferred to <see cref="Network.DeStreamWallet"/> /// A rule that verifies fee is charged from all spent funds and transferred to <see cref="Network.DeStreamWallet"/>
/// </summary> /// </summary>
[ExecutionRule] public class DeStreamBlockFeeRule : FullValidationConsensusRule
public class DeStreamBlockFeeRule : ConsensusRule
{ {
private DeStreamNetwork DeStreamNetwork
{
get
{
if (!(this.Parent.Network is DeStreamNetwork))
throw new NotSupportedException($"Network must be {nameof(NBitcoin.DeStreamNetwork)}");
return (DeStreamNetwork) this.Parent.Network;
}
}
public override Task RunAsync(RuleContext context) public override Task RunAsync(RuleContext context)
{ {
// Actual fee is funds that are transferred to fee wallet in mined/staked block // Actual fee is funds that are transferred to fee wallet in mined/staked block
long actualFee = this.GetActualFee(context.ValidationContext.Block); long actualFee = this.GetActualFee(context.ValidationContext.BlockToValidate);
// Expected fee is charged from all moved funds (not change) // Expected fee is charged from all moved funds (not change)
long expectedFee; long expectedFee;
switch (context) switch (context)
{ {
case DeStreamPowRuleContext deStreamPowRuleContext: case DeStreamPowRuleContext deStreamPowRuleContext:
expectedFee = this.GetExpectedFee(context.ValidationContext.Block, deStreamPowRuleContext.TotalIn, expectedFee = this.GetExpectedFee(context.ValidationContext.BlockToValidate, deStreamPowRuleContext.TotalIn,
deStreamPowRuleContext.InputScriptPubKeys); deStreamPowRuleContext.InputScriptPubKeys);
break; break;
case DeStreamRuleContext deStreamPosRuleContext: case DeStreamPosRuleContext deStreamPosRuleContext:
expectedFee = this.GetExpectedFee(context.ValidationContext.Block, deStreamPosRuleContext.TotalIn, expectedFee = this.GetExpectedFee(context.ValidationContext.BlockToValidate, deStreamPosRuleContext.TotalIn,
deStreamPosRuleContext.InputScriptPubKeys); deStreamPosRuleContext.InputScriptPubKeys);
break; break;
default: default:
throw new NotSupportedException( throw new NotSupportedException(
$"Rule context must be {nameof(DeStreamPowRuleContext)} or {nameof(DeStreamRuleContext)}"); $"Rule context must be {nameof(DeStreamPowRuleContext)} or {nameof(DeStreamPosRuleContext)}");
} }
this.Parent.Network.SplitFee(expectedFee, out long expectedDeStreamFee, out long _); this.DeStreamNetwork.SplitFee(expectedFee, out long expectedDeStreamFee, out long _);
if (actualFee < expectedDeStreamFee) if (actualFee < expectedDeStreamFee)
ConsensusErrors.BadTransactionFeeOutOfRange.Throw(); ConsensusErrors.BadTransactionFeeOutOfRange.Throw();
...@@ -46,8 +56,8 @@ namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules ...@@ -46,8 +56,8 @@ namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules
private long GetActualFee(Block block) private long GetActualFee(Block block)
{ {
IList<TxOut> outputsToFeeWallet = block.Transactions[BlockStake.IsProofOfStake(block) ? 1 : 0].Outputs IList<TxOut> outputsToFeeWallet = block.Transactions[BlockStake.IsProofOfStake(block) ? 1 : 0].Outputs
.Where(p => this.Parent.Network.IsDeStreamAddress(p.ScriptPubKey .Where(p => this.DeStreamNetwork.IsDeStreamAddress(p.ScriptPubKey
.GetDestinationAddress(this.Parent.Network)?.ToString())).ToList(); .GetDestinationAddress(this.DeStreamNetwork)?.ToString())).ToList();
if (outputsToFeeWallet.Count != 1) if (outputsToFeeWallet.Count != 1)
ConsensusErrors.BadBlockNoFeeOutput.Throw(); ConsensusErrors.BadBlockNoFeeOutput.Throw();
...@@ -71,7 +81,7 @@ namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules ...@@ -71,7 +81,7 @@ namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules
{ {
long feeInTransaction = Convert.ToInt64(transaction.Outputs long feeInTransaction = Convert.ToInt64(transaction.Outputs
.Where(p => !changeScriptPubKeys.Contains(p.ScriptPubKey)) .Where(p => !changeScriptPubKeys.Contains(p.ScriptPubKey))
.Sum(p => p.Value) * this.Parent.Network.FeeRate); .Sum(p => p.Value) * this.DeStreamNetwork.FeeRate);
if (Math.Abs(totalIn.Satoshi - transaction.TotalOut.Satoshi - feeInTransaction) > 1) if (Math.Abs(totalIn.Satoshi - transaction.TotalOut.Satoshi - feeInTransaction) > 1)
ConsensusErrors.BadTransactionFeeOutOfRange.Throw(); ConsensusErrors.BadTransactionFeeOutOfRange.Throw();
......
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