Commit 30d9620f authored by Sergei Zubov's avatar Sergei Zubov

Merge mempool

parent 73ee2662
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework> <TargetFramework>netcoreapp2.1</TargetFramework>
<AssemblyName>Stratis.Bitcoin.Features.MemoryPool.Tests</AssemblyName> <AssemblyName>Stratis.Bitcoin.Features.MemoryPool.Tests</AssemblyName>
...@@ -16,17 +15,14 @@ ...@@ -16,17 +15,14 @@
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute> <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<CodeAnalysisRuleSet>..\None.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>..\None.ruleset</CodeAnalysisRuleSet>
</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>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="Stratis.Bitcoin.Features.MemoryPool.Tests\**" /> <Compile Remove="Stratis.Bitcoin.Features.MemoryPool.Tests\**" />
<EmbeddedResource Remove="Stratis.Bitcoin.Features.MemoryPool.Tests\**" /> <EmbeddedResource Remove="Stratis.Bitcoin.Features.MemoryPool.Tests\**" />
<None Remove="Stratis.Bitcoin.Features.MemoryPool.Tests\**" /> <None Remove="Stratis.Bitcoin.Features.MemoryPool.Tests\**" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DBreeze" Version="1.89.0" /> <PackageReference Include="DBreeze" Version="1.89.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
...@@ -35,7 +31,6 @@ ...@@ -35,7 +31,6 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\NBitcoin\NBitcoin.csproj" /> <ProjectReference Include="..\NBitcoin\NBitcoin.csproj" />
<ProjectReference Include="..\Stratis.Bitcoin.Features.BlockStore\Stratis.Bitcoin.Features.BlockStore.csproj" /> <ProjectReference Include="..\Stratis.Bitcoin.Features.BlockStore\Stratis.Bitcoin.Features.BlockStore.csproj" />
...@@ -45,15 +40,12 @@ ...@@ -45,15 +40,12 @@
<ProjectReference Include="..\Stratis.Bitcoin.Tests.Common\Stratis.Bitcoin.Tests.Common.csproj" /> <ProjectReference Include="..\Stratis.Bitcoin.Tests.Common\Stratis.Bitcoin.Tests.Common.csproj" />
<ProjectReference Include="..\Stratis.Bitcoin\Stratis.Bitcoin.csproj" /> <ProjectReference Include="..\Stratis.Bitcoin\Stratis.Bitcoin.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="xunit.runner.json"> <None Update="xunit.runner.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
</Project> </Project>
\ No newline at end of file
...@@ -11,11 +11,13 @@ using Stratis.Bitcoin.Utilities; ...@@ -11,11 +11,13 @@ using Stratis.Bitcoin.Utilities;
namespace Stratis.Bitcoin.Features.MemoryPool namespace Stratis.Bitcoin.Features.MemoryPool
{ {
/// <summary> /// <summary>
/// Creates <see cref="DeStreamUnspentOutputSet"/> and ChangePointer input /// Creates <see cref="DeStreamUnspentOutputSet" /> and ChangePointer input
/// </summary> /// </summary>
public class DeStreamMempoolCoinView : MempoolCoinView public class DeStreamMempoolCoinView : MempoolCoinView
{ {
public DeStreamMempoolCoinView(CoinView inner, ITxMempool memPool, SchedulerLock mempoolLock, IMempoolValidator mempoolValidator) : base(inner, memPool, mempoolLock, mempoolValidator) public DeStreamMempoolCoinView(ICoinView inner, ITxMempool memPool, SchedulerLock mempoolLock,
IMempoolValidator mempoolValidator)
: base(inner, memPool, mempoolLock, mempoolValidator)
{ {
this.Set = new DeStreamUnspentOutputSet(); this.Set = new DeStreamUnspentOutputSet();
} }
...@@ -23,15 +25,21 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -23,15 +25,21 @@ namespace Stratis.Bitcoin.Features.MemoryPool
public override async Task LoadViewAsync(Transaction trx) public override async Task LoadViewAsync(Transaction trx)
{ {
// lookup all ids (duplicate ids are ignored in case a trx spends outputs from the same parent). // lookup all ids (duplicate ids are ignored in case a trx spends outputs from the same parent).
List<uint256> ids = trx.Inputs.RemoveChangePointer().Select(n => n.PrevOut.Hash).Distinct().Concat(new[] { trx.GetHash() }).ToList(); List<uint256> ids = trx.Inputs.RemoveChangePointer().Select(n => n.PrevOut.Hash).Distinct()
.Concat(new[] {trx.GetHash()}).ToList();
FetchCoinsResponse coins = await this.Inner.FetchCoinsAsync(ids.ToArray()); FetchCoinsResponse coins = await this.Inner.FetchCoinsAsync(ids.ToArray());
// find coins currently in the mempool // find coins currently in the mempool
List<Transaction> mempoolcoins = await this.mempoolLock.ReadAsync(() => List<Transaction> mempoolcoins = await this.mempoolLock.ReadAsync(() =>
{ {
return this.memPool.MapTx.Values.Where(t => ids.Contains(t.TransactionHash)).Select(s => s.Transaction).ToList(); return this.memPool.MapTx.Values.Where(t => ids.Contains(t.TransactionHash))
.Select(s => s.Transaction).ToList();
}); });
IEnumerable<UnspentOutputs> memOutputs = mempoolcoins.Select(s => new UnspentOutputs(TxMempool.MempoolHeight, s)); IEnumerable<UnspentOutputs> memOutputs =
coins = new FetchCoinsResponse(coins.UnspentOutputs.Concat(memOutputs).Append(new UnspentOutputs(uint256.Zero, new Coins(new Transaction(), 0))).ToArray(), coins.BlockHash); mempoolcoins.Select(s => new UnspentOutputs(TxMempool.MempoolHeight, s));
coins = new FetchCoinsResponse(
coins.UnspentOutputs.Concat(memOutputs)
.Append(new UnspentOutputs(uint256.Zero, new Coins(new Transaction(), 0))).ToArray(),
coins.BlockHash);
// the UTXO set might have been updated with a recently received block // the UTXO set might have been updated with a recently received block
// but the block has not yet arrived to the mempool and remove the pending trx // but the block has not yet arrived to the mempool and remove the pending trx
......
...@@ -8,22 +8,23 @@ using Stratis.Bitcoin.Utilities; ...@@ -8,22 +8,23 @@ using Stratis.Bitcoin.Utilities;
namespace Stratis.Bitcoin.Features.MemoryPool namespace Stratis.Bitcoin.Features.MemoryPool
{ {
/// <summary> /// <summary>
/// Creates <see cref="DeStreamMempoolCoinView"/> /// Creates <see cref="DeStreamMempoolCoinView" />
/// </summary> /// </summary>
public class DeStreamMempoolManager : MempoolManager public class DeStreamMempoolManager : MempoolManager
{ {
public DeStreamMempoolManager(MempoolSchedulerLock mempoolLock, ITxMempool memPool, IMempoolValidator validator, IDateTimeProvider dateTimeProvider, MempoolSettings mempoolSettings, IMempoolPersistence mempoolPersistence, CoinView coinView, ILoggerFactory loggerFactory, Network network) : base(mempoolLock, memPool, validator, dateTimeProvider, mempoolSettings, mempoolPersistence, coinView, loggerFactory, network) public DeStreamMempoolManager(MempoolSchedulerLock mempoolLock, ITxMempool memPool, IMempoolValidator validator,
IDateTimeProvider dateTimeProvider, MempoolSettings mempoolSettings, IMempoolPersistence mempoolPersistence,
ICoinView coinView, ILoggerFactory loggerFactory, Network network) : base(mempoolLock, memPool, validator,
dateTimeProvider, mempoolSettings, mempoolPersistence, coinView, loggerFactory, network)
{ {
} }
public override async Task<UnspentOutputs> GetUnspentTransactionAsync(uint256 trxid) public override async Task<UnspentOutputs> GetUnspentTransactionAsync(uint256 trxid)
{ {
TxMempoolInfo txInfo = await this.InfoAsync(trxid); TxMempoolInfo txInfo = await InfoAsync(trxid);
if (txInfo == null) if (txInfo == null) return null;
{ var memPoolCoinView =
return null; new DeStreamMempoolCoinView(this.coinView, this.memPool, this.MempoolLock, this.Validator);
}
var memPoolCoinView = new DeStreamMempoolCoinView(this.coinView, this.memPool, this.MempoolLock, this.Validator);
await memPoolCoinView.LoadViewAsync(txInfo.Trx); await memPoolCoinView.LoadViewAsync(txInfo.Trx);
return memPoolCoinView.GetCoins(trxid); return memPoolCoinView.GetCoins(trxid);
} }
......
...@@ -5,7 +5,7 @@ using System.Threading.Tasks; ...@@ -5,7 +5,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NBitcoin; using NBitcoin;
using Stratis.Bitcoin.Configuration; using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Consensus.Rules; using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.Features.Consensus.CoinViews; using Stratis.Bitcoin.Features.Consensus.CoinViews;
using Stratis.Bitcoin.Features.MemoryPool.Interfaces; using Stratis.Bitcoin.Features.MemoryPool.Interfaces;
using Stratis.Bitcoin.Utilities; using Stratis.Bitcoin.Utilities;
...@@ -19,18 +19,28 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -19,18 +19,28 @@ namespace Stratis.Bitcoin.Features.MemoryPool
{ {
public DeStreamMempoolValidator(ITxMempool memPool, MempoolSchedulerLock mempoolLock, public DeStreamMempoolValidator(ITxMempool memPool, MempoolSchedulerLock mempoolLock,
IDateTimeProvider dateTimeProvider, MempoolSettings mempoolSettings, ConcurrentChain chain, IDateTimeProvider dateTimeProvider, MempoolSettings mempoolSettings, ConcurrentChain chain,
CoinView coinView, ILoggerFactory loggerFactory, NodeSettings nodeSettings, IConsensusRules consensusRules) ICoinView coinView, ILoggerFactory loggerFactory, NodeSettings nodeSettings,
: base(memPool, mempoolLock, dateTimeProvider, mempoolSettings, chain, coinView, loggerFactory, IConsensusRuleEngine consensusRules) : base(memPool, mempoolLock, dateTimeProvider, mempoolSettings, chain,
nodeSettings, consensusRules) coinView, loggerFactory, nodeSettings, consensusRules)
{ {
} }
private DeStreamNetwork DeStreamNetwork
{
get
{
if (!(this.network is DeStreamNetwork))
throw new NotSupportedException($"Network must be {nameof(NBitcoin.DeStreamNetwork)}");
return (DeStreamNetwork) this.network;
}
}
protected override async Task AcceptToMemoryPoolWorkerAsync(MempoolValidationState state, Transaction tx, protected override async Task AcceptToMemoryPoolWorkerAsync(MempoolValidationState state, Transaction tx,
List<uint256> vHashTxnToUncache) List<uint256> vHashTxnToUncache)
{ {
var context = new MempoolValidationContext(tx, state); var context = new MempoolValidationContext(tx, state);
this.PreMempoolChecks(context); PreMempoolChecks(context);
// create the MemPoolCoinView and load relevant utxoset // create the MemPoolCoinView and load relevant utxoset
context.View = new DeStreamMempoolCoinView(this.coinView, this.memPool, this.mempoolLock, this); context.View = new DeStreamMempoolCoinView(this.coinView, this.memPool, this.mempoolLock, this);
...@@ -45,33 +55,31 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -45,33 +55,31 @@ namespace Stratis.Bitcoin.Features.MemoryPool
state.Invalid(MempoolErrors.InPool).Throw(); state.Invalid(MempoolErrors.InPool).Throw();
// Check for conflicts with in-memory transactions // Check for conflicts with in-memory transactions
this.CheckConflicts(context); CheckConflicts(context);
this.CheckMempoolCoinView(context); CheckMempoolCoinView(context);
this.CreateMempoolEntry(context, state.AcceptTime); CreateMempoolEntry(context, state.AcceptTime);
this.CheckSigOps(context); CheckSigOps(context);
this.CheckFee(context); CheckFee(context);
this.CheckRateLimit(context, state.LimitFree); CheckRateLimit(context, state.LimitFree);
this.CheckAncestors(context); CheckAncestors(context);
this.CheckReplacment(context); CheckReplacment(context);
this.CheckAllInputs(context); CheckAllInputs(context);
// Remove conflicting transactions from the mempool // Remove conflicting transactions from the mempool
foreach (TxMempoolEntry it in context.AllConflicting) foreach (TxMempoolEntry it in context.AllConflicting)
{
this.logger.LogInformation( this.logger.LogInformation(
$"replacing tx {it.TransactionHash} with {context.TransactionHash} for {context.ModifiedFees - context.ConflictingFees} BTC additional fees, {context.EntrySize - context.ConflictingSize} delta bytes"); $"replacing tx {it.TransactionHash} with {context.TransactionHash} for {context.ModifiedFees - context.ConflictingFees} BTC additional fees, {context.EntrySize - context.ConflictingSize} delta bytes");
}
this.memPool.RemoveStaged(context.AllConflicting, false); this.memPool.RemoveStaged(context.AllConflicting, false);
// This transaction should only count for fee estimation if // This transaction should only count for fee estimation if
// the node is not behind and it is not dependent on any other // the node is not behind and it is not dependent on any other
// transactions in the mempool // transactions in the mempool
bool validForFeeEstimation = this.IsCurrentForFeeEstimation() && this.memPool.HasNoInputsOf(tx); bool validForFeeEstimation = IsCurrentForFeeEstimation() && this.memPool.HasNoInputsOf(tx);
// Store transaction in memory // Store transaction in memory
this.memPool.AddUnchecked(context.TransactionHash, context.Entry, context.SetAncestors, this.memPool.AddUnchecked(context.TransactionHash, context.Entry, context.SetAncestors,
...@@ -80,7 +88,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -80,7 +88,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
// trim mempool and check if tx was trimmed // trim mempool and check if tx was trimmed
if (!state.OverrideMempoolLimit) if (!state.OverrideMempoolLimit)
{ {
this.LimitMempoolSize(this.mempoolSettings.MaxMempool * 1000000, LimitMempoolSize(this.mempoolSettings.MaxMempool * 1000000,
this.mempoolSettings.MempoolExpiry * 60 * 60); this.mempoolSettings.MempoolExpiry * 60 * 60);
if (!this.memPool.Exists(context.TransactionHash)) if (!this.memPool.Exists(context.TransactionHash))
...@@ -172,7 +180,6 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -172,7 +180,6 @@ namespace Stratis.Bitcoin.Features.MemoryPool
// insecure. // insecure.
bool replacementOptOut = true; bool replacementOptOut = true;
if (this.mempoolSettings.EnableReplacement) if (this.mempoolSettings.EnableReplacement)
{
foreach (TxIn txiner in ptxConflicting.Inputs) foreach (TxIn txiner in ptxConflicting.Inputs)
{ {
if (txiner.Sequence >= Sequence.Final - 1) continue; if (txiner.Sequence >= Sequence.Final - 1) continue;
...@@ -180,7 +187,6 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -180,7 +187,6 @@ namespace Stratis.Bitcoin.Features.MemoryPool
replacementOptOut = false; replacementOptOut = false;
break; break;
} }
}
if (replacementOptOut) if (replacementOptOut)
context.State.Invalid(MempoolErrors.Conflict).Throw(); context.State.Invalid(MempoolErrors.Conflict).Throw();
...@@ -193,7 +199,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -193,7 +199,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// Validates the transaction fee is valid. /// Validates the transaction fee is valid.
/// </summary> /// </summary>
/// <param name="context">Current validation context.</param> /// <param name="context">Current validation context.</param>
protected override void CheckFee(MempoolValidationContext context) public override void CheckFee(MempoolValidationContext context)
{ {
long expectedFee = Convert.ToInt64(context.Transaction.Outputs long expectedFee = Convert.ToInt64(context.Transaction.Outputs
.Where(p => !context.Transaction.Inputs.RemoveChangePointer() .Where(p => !context.Transaction.Inputs.RemoveChangePointer()
...@@ -201,7 +207,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -201,7 +207,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
.Concat(context.Transaction.Inputs.GetChangePointers() .Concat(context.Transaction.Inputs.GetChangePointers()
.Select(q => context.Transaction.Outputs[q].ScriptPubKey)) .Select(q => context.Transaction.Outputs[q].ScriptPubKey))
.Contains(p.ScriptPubKey)) .Contains(p.ScriptPubKey))
.Sum(p => p.Value) * this.network.FeeRate); .Sum(p => p.Value) * this.DeStreamNetwork.FeeRate);
if (context.ModifiedFees < expectedFee) if (context.ModifiedFees < expectedFee)
context.State.Fail(MempoolErrors.InsufficientFee, $" {context.Fees} < {expectedFee}").Throw(); context.State.Fail(MempoolErrors.InsufficientFee, $" {context.Fees} < {expectedFee}").Throw();
......
...@@ -19,10 +19,10 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -19,10 +19,10 @@ namespace Stratis.Bitcoin.Features.MemoryPool
{ {
/// <summary>Transaction memory pool for managing transactions in the memory pool.</summary> /// <summary>Transaction memory pool for managing transactions in the memory pool.</summary>
/// <remarks>All access to this object has to be protected by <see cref="mempoolLock"/>.</remarks> /// <remarks>All access to this object has to be protected by <see cref="mempoolLock"/>.</remarks>
private readonly ITxMempool memPool; protected readonly ITxMempool memPool;
/// <summary>A lock for protecting access to <see cref="memPool"/>.</summary> /// <summary>A lock for protecting access to <see cref="memPool"/>.</summary>
private readonly SchedulerLock mempoolLock; protected readonly SchedulerLock mempoolLock;
/// <summary>Memory pool validator for validating transactions.</summary> /// <summary>Memory pool validator for validating transactions.</summary>
private readonly IMempoolValidator mempoolValidator; private readonly IMempoolValidator mempoolValidator;
...@@ -46,7 +46,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -46,7 +46,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// <summary> /// <summary>
/// Gets the unspent transaction output set. /// Gets the unspent transaction output set.
/// </summary> /// </summary>
public UnspentOutputSet Set { get; private set; } public UnspentOutputSet Set { get; protected set; }
/// <summary> /// <summary>
/// Backing coin view instance. /// Backing coin view instance.
...@@ -87,7 +87,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -87,7 +87,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// Load the coin view for a memory pool transaction. /// Load the coin view for a memory pool transaction.
/// </summary> /// </summary>
/// <param name="trx">Memory pool transaction.</param> /// <param name="trx">Memory pool transaction.</param>
public async Task LoadViewAsync(Transaction trx) public virtual async Task LoadViewAsync(Transaction trx)
{ {
// lookup all ids (duplicate ids are ignored in case a trx spends outputs from the same parent). // lookup all ids (duplicate ids are ignored in case a trx spends outputs from the same parent).
List<uint256> ids = trx.Inputs.Select(n => n.PrevOut.Hash).Distinct().Concat(new[] { trx.GetHash() }).ToList(); List<uint256> ids = trx.Inputs.Select(n => n.PrevOut.Hash).Distinct().Concat(new[] { trx.GetHash() }).ToList();
......
...@@ -32,10 +32,10 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -32,10 +32,10 @@ namespace Stratis.Bitcoin.Features.MemoryPool
private readonly ILogger logger; private 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>
private readonly ITxMempool memPool; protected readonly ITxMempool memPool;
/// <summary>Coin view of the memory pool.</summary> /// <summary>Coin view of the memory pool.</summary>
private readonly ICoinView coinView; protected readonly ICoinView coinView;
private readonly Network network; private readonly Network network;
...@@ -217,7 +217,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -217,7 +217,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
} }
/// <inheritdoc /> /// <inheritdoc />
public async Task<UnspentOutputs> GetUnspentTransactionAsync(uint256 trxid) public virtual async Task<UnspentOutputs> GetUnspentTransactionAsync(uint256 trxid)
{ {
TxMempoolInfo txInfo = await this.InfoAsync(trxid); TxMempoolInfo txInfo = await this.InfoAsync(trxid);
if (txInfo == null) if (txInfo == null)
......
...@@ -114,28 +114,28 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -114,28 +114,28 @@ namespace Stratis.Bitcoin.Features.MemoryPool
private const int MaxFeeEstimationTipAge = 3 * 60 * 60; private const int MaxFeeEstimationTipAge = 3 * 60 * 60;
/// <summary>A lock for managing asynchronous access to memory pool.</summary> /// <summary>A lock for managing asynchronous access to memory pool.</summary>
private readonly MempoolSchedulerLock mempoolLock; protected readonly MempoolSchedulerLock mempoolLock;
/// <summary>Date and time information provider.</summary> /// <summary>Date and time information provider.</summary>
private readonly IDateTimeProvider dateTimeProvider; private readonly IDateTimeProvider dateTimeProvider;
/// <summary>Settings from the memory pool.</summary> /// <summary>Settings from the memory pool.</summary>
private readonly MempoolSettings mempoolSettings; protected readonly MempoolSettings mempoolSettings;
/// <summary>Thread safe access to the best chain of block headers (that the node is aware of) from genesis.</summary> /// <summary>Thread safe access to the best chain of block headers (that the node is aware of) from genesis.</summary>
private readonly ConcurrentChain chain; private readonly ConcurrentChain chain;
/// <summary>Coin view of the memory pool.</summary> /// <summary>Coin view of the memory pool.</summary>
private readonly ICoinView coinView; protected readonly ICoinView coinView;
/// <inheritdoc cref="IConsensusRuleEngine" /> /// <inheritdoc cref="IConsensusRuleEngine" />
private readonly IConsensusRuleEngine consensusRules; private readonly IConsensusRuleEngine consensusRules;
/// <summary>Transaction memory pool for managing transactions in the memory pool.</summary> /// <summary>Transaction memory pool for managing transactions in the memory pool.</summary>
private readonly ITxMempool memPool; protected readonly ITxMempool memPool;
/// <summary>Instance logger for memory pool validator.</summary> /// <summary>Instance logger for memory pool validator.</summary>
private readonly ILogger logger; protected readonly ILogger logger;
/// <summary>Minimum fee rate for a relay transaction.</summary> /// <summary>Minimum fee rate for a relay transaction.</summary>
private readonly FeeRate minRelayTxFee; private readonly FeeRate minRelayTxFee;
...@@ -152,7 +152,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -152,7 +152,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
// public long LastTime; // public long LastTime;
//} //}
private Network network; protected Network network;
public MempoolValidator( public MempoolValidator(
ITxMempool memPool, ITxMempool memPool,
...@@ -413,7 +413,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -413,7 +413,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// <param name="state">Validation state for creating the validation context.</param> /// <param name="state">Validation state for creating the validation context.</param>
/// <param name="tx">The transaction to validate.</param> /// <param name="tx">The transaction to validate.</param>
/// <param name="vHashTxnToUncache">Not currently used</param> /// <param name="vHashTxnToUncache">Not currently used</param>
private async Task AcceptToMemoryPoolWorkerAsync(MempoolValidationState state, Transaction tx, List<uint256> vHashTxnToUncache) protected virtual async Task AcceptToMemoryPoolWorkerAsync(MempoolValidationState state, Transaction tx, List<uint256> vHashTxnToUncache)
{ {
var context = new MempoolValidationContext(tx, state); var context = new MempoolValidationContext(tx, state);
...@@ -491,7 +491,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -491,7 +491,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// If a conflict is found it is added to the validation context. /// If a conflict is found it is added to the validation context.
/// </summary> /// </summary>
/// <param name="context">Current validation context.</param> /// <param name="context">Current validation context.</param>
private void CheckConflicts(MempoolValidationContext context) protected virtual void CheckConflicts(MempoolValidationContext context)
{ {
context.SetConflicts = new List<uint256>(); context.SetConflicts = new List<uint256>();
foreach (TxIn txin in context.Transaction.Inputs) foreach (TxIn txin in context.Transaction.Inputs)
...@@ -691,7 +691,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -691,7 +691,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// Checks if already in coin view, and missing and unavailable inputs. /// Checks if already in coin view, and missing and unavailable inputs.
/// </summary> /// </summary>
/// <param name="context">Validation context.</param> /// <param name="context">Validation context.</param>
private void CheckMempoolCoinView(MempoolValidationContext context) protected virtual void CheckMempoolCoinView(MempoolValidationContext context)
{ {
Guard.Assert(context.View != null); Guard.Assert(context.View != null);
...@@ -758,7 +758,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -758,7 +758,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// Check that the transaction doesn't have an excessive number of sigops. /// Check that the transaction doesn't have an excessive number of sigops.
/// </summary> /// </summary>
/// <param name="context">Current validation context.</param> /// <param name="context">Current validation context.</param>
private void CheckSigOps(MempoolValidationContext context) protected void CheckSigOps(MempoolValidationContext context)
{ {
// Check that the transaction doesn't have an excessive number of // Check that the transaction doesn't have an excessive number of
// sigops, making it impossible to mine. Since the coinbase transaction // sigops, making it impossible to mine. Since the coinbase transaction
...@@ -779,7 +779,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -779,7 +779,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// </summary> /// </summary>
/// <param name="context">Current validation context.</param> /// <param name="context">Current validation context.</param>
/// <param name="acceptTime">The accept time to use for the entry.</param> /// <param name="acceptTime">The accept time to use for the entry.</param>
private void CreateMempoolEntry(MempoolValidationContext context, long acceptTime) protected void CreateMempoolEntry(MempoolValidationContext context, long acceptTime)
{ {
// Only accept BIP68 sequence locked transactions that can be mined in the next // Only accept BIP68 sequence locked transactions that can be mined in the next
// block; we don't want our mempool filled up with transactions that can't // block; we don't want our mempool filled up with transactions that can't
...@@ -838,7 +838,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -838,7 +838,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// The new transaction must have sufficient fees to pay for it's bandwidth. /// The new transaction must have sufficient fees to pay for it's bandwidth.
/// </summary> /// </summary>
/// <param name="context">Current validation context.</param> /// <param name="context">Current validation context.</param>
private void CheckReplacment(MempoolValidationContext context) protected void CheckReplacment(MempoolValidationContext context)
{ {
// Check if it's economically rational to mine this transaction rather // Check if it's economically rational to mine this transaction rather
// than the ones it replaces. // than the ones it replaces.
...@@ -969,7 +969,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -969,7 +969,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// </summary> /// </summary>
/// <param name="context">Current validation context</param> /// <param name="context">Current validation context</param>
/// <param name="limitFree">Whether to limit free transactioins</param> /// <param name="limitFree">Whether to limit free transactioins</param>
private void CheckRateLimit(MempoolValidationContext context, bool limitFree) protected void CheckRateLimit(MempoolValidationContext context, bool limitFree)
{ {
// TODO: sort this logic // TODO: sort this logic
return; return;
...@@ -981,7 +981,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -981,7 +981,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// Checks for a transaction that spends outputs that would be replaced by it. /// Checks for a transaction that spends outputs that would be replaced by it.
/// </summary> /// </summary>
/// <param name="context">Current validation context.</param> /// <param name="context">Current validation context.</param>
private void CheckAncestors(MempoolValidationContext context) protected void CheckAncestors(MempoolValidationContext context)
{ {
// Calculate in-mempool ancestors, up to a limit. // Calculate in-mempool ancestors, up to a limit.
context.SetAncestors = new TxMempool.SetEntries(); context.SetAncestors = new TxMempool.SetEntries();
...@@ -1020,7 +1020,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -1020,7 +1020,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// </summary> /// </summary>
/// <param name="limit">New size.</param> /// <param name="limit">New size.</param>
/// <param name="age">AAge to use for calculating expired transactions.</param> /// <param name="age">AAge to use for calculating expired transactions.</param>
private void LimitMempoolSize(long limit, long age) protected void LimitMempoolSize(long limit, long age)
{ {
int expired = this.memPool.Expire(this.dateTimeProvider.GetTime() - age); int expired = this.memPool.Expire(this.dateTimeProvider.GetTime() - age);
if (expired != 0) if (expired != 0)
...@@ -1035,7 +1035,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -1035,7 +1035,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// It should only count for fee estimation if the node is not behind. /// It should only count for fee estimation if the node is not behind.
/// </summary> /// </summary>
/// <returns>Whether current for fee estimation.</returns> /// <returns>Whether current for fee estimation.</returns>
private bool IsCurrentForFeeEstimation() protected bool IsCurrentForFeeEstimation()
{ {
// TODO: implement method (find a way to know if in IBD) // TODO: implement method (find a way to know if in IBD)
...@@ -1058,7 +1058,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -1058,7 +1058,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// Checks against <see cref="ScriptVerify.Standard"/> and <see cref="ScriptVerify.P2SH"/> /// Checks against <see cref="ScriptVerify.Standard"/> and <see cref="ScriptVerify.P2SH"/>
/// </summary> /// </summary>
/// <param name="context">Current validation context.</param> /// <param name="context">Current validation context.</param>
private void CheckAllInputs(MempoolValidationContext context) protected void CheckAllInputs(MempoolValidationContext context)
{ {
var scriptVerifyFlags = ScriptVerify.Standard; var scriptVerifyFlags = ScriptVerify.Standard;
if (!this.mempoolSettings.RequireStandard) if (!this.mempoolSettings.RequireStandard)
...@@ -1177,7 +1177,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool ...@@ -1177,7 +1177,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool
/// <param name="tx">Transaction to verify.</param> /// <param name="tx">Transaction to verify.</param>
/// <param name="mapInputs">Map of previous transactions that have outputs we're spending.</param> /// <param name="mapInputs">Map of previous transactions that have outputs we're spending.</param>
/// <returns>Whether all inputs (scriptSigs) use only standard transaction forms.</returns> /// <returns>Whether all inputs (scriptSigs) use only standard transaction forms.</returns>
private bool AreInputsStandard(Transaction tx, MempoolCoinView mapInputs) protected virtual bool AreInputsStandard(Transaction tx, MempoolCoinView mapInputs)
{ {
if (tx.IsCoinBase) if (tx.IsCoinBase)
{ {
......
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