Commit 12dd1aa9 authored by Sergei Zubov's avatar Sergei Zubov

Merge load coinview rule

parent 9c01aab4
...@@ -115,7 +115,7 @@ namespace Stratis.Bitcoin.Features.Consensus ...@@ -115,7 +115,7 @@ namespace Stratis.Bitcoin.Features.Consensus
new SetActivationDeploymentsFullValidationRule(), new SetActivationDeploymentsFullValidationRule(),
// rules that require the store to be loaded (coinview) // rules that require the store to be loaded (coinview)
new LoadCoinviewRule(), new DeStreamLoadCoinviewRule(),
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(),
...@@ -173,7 +173,7 @@ namespace Stratis.Bitcoin.Features.Consensus ...@@ -173,7 +173,7 @@ namespace Stratis.Bitcoin.Features.Consensus
new CheckDifficultyHybridRule(), new CheckDifficultyHybridRule(),
// rules that require the store to be loaded (coinview) // rules that require the store to be loaded (coinview)
new LoadCoinviewRule(), new DeStreamLoadCoinviewRule(),
new TransactionDuplicationActivationRule(), // implements BIP30 new TransactionDuplicationActivationRule(), // implements BIP30
new DeStreamPosCoinviewRule(), // implements BIP68, MaxSigOps and BlockReward calculation new DeStreamPosCoinviewRule(), // implements BIP68, MaxSigOps and BlockReward calculation
// 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
......
...@@ -4,74 +4,48 @@ using System.Linq; ...@@ -4,74 +4,48 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NBitcoin; using NBitcoin;
using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.Consensus.Rules; using Stratis.Bitcoin.Consensus.Rules;
using Stratis.Bitcoin.Features.Consensus.CoinViews; using Stratis.Bitcoin.Features.Consensus.CoinViews;
using Stratis.Bitcoin.Utilities; using Stratis.Bitcoin.Utilities;
namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules
{ {
[ExecutionRule]
public class DeStreamLoadCoinviewRule : LoadCoinviewRule public class DeStreamLoadCoinviewRule : LoadCoinviewRule
{ {
public override async Task RunAsync(RuleContext context) public override async Task RunAsync(RuleContext context)
{ {
var utxoRuleContext = context as UtxoRuleContext; // Check that the current block has not been reorged.
// Catching a reorg at this point will not require a rewind.
if (context.ValidationContext.BlockToValidate.Header.HashPrevBlock != this.Parent.ChainState.ConsensusTip.HashBlock)
{
this.Logger.LogTrace("Reorganization detected.");
ConsensusErrors.InvalidPrevTip.Throw();
}
// Load the UTXO set of the current block. UTXO may be loaded from cache or from disk. var utxoRuleContext = context as UtxoRuleContext;
// The UTXO set is stored in the context.
this.Logger.LogTrace("Loading UTXO set of the new block.");
utxoRuleContext.UnspentOutputSet = new DeStreamUnspentOutputSet();
switch (utxoRuleContext) switch (utxoRuleContext)
{ {
case DeStreamPowRuleContext deStreamPowRuleContext: case DeStreamPowRuleContext deStreamPowRuleContext:
deStreamPowRuleContext.InputScriptPubKeys = new Dictionary<uint256, List<Script>>(); deStreamPowRuleContext.InputScriptPubKeys = new Dictionary<uint256, List<Script>>();
break; break;
case DeStreamRuleContext deStreamPosRuleContext: case DeStreamPosRuleContext deStreamPosRuleContext:
deStreamPosRuleContext.InputScriptPubKeys = new Dictionary<uint256, List<Script>>(); deStreamPosRuleContext.InputScriptPubKeys = new Dictionary<uint256, List<Script>>();
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)}");
} }
using (new StopwatchDisposable(o => this.Parent.PerformanceCounter.AddUTXOFetchingTime(o))) // Load the UTXO set of the current block. UTXO may be loaded from cache or from disk.
{ // The UTXO set is stored in the context.
uint256[] ids = this.GetIdsToFetch(context.ValidationContext.Block, context.Flags.EnforceBIP30); this.Logger.LogTrace("Loading UTXO set of the new block.");
utxoRuleContext.UnspentOutputSet = new DeStreamUnspentOutputSet();
uint256[] ids = this.coinviewHelper.GetIdsToFetch(context.ValidationContext.BlockToValidate, context.Flags.EnforceBIP30);
FetchCoinsResponse coins = await this.PowParent.UtxoSet.FetchCoinsAsync(ids).ConfigureAwait(false); FetchCoinsResponse coins = await this.PowParent.UtxoSet.FetchCoinsAsync(ids).ConfigureAwait(false);
utxoRuleContext.UnspentOutputSet.SetCoins(coins.UnspentOutputs); utxoRuleContext.UnspentOutputSet.SetCoins(coins.UnspentOutputs);
} }
// Attempt to load into the cache the next set of UTXO to be validated.
// The task is not awaited so will not stall main validation process.
this.TryPrefetchAsync(context.Flags);
}
/// <inheritdoc />
protected override uint256[] GetIdsToFetch(Block block, bool enforceBIP30)
{
this.Logger.LogTrace("({0}:'{1}',{2}:{3})", nameof(block), block.GetHash(), nameof(enforceBIP30), enforceBIP30);
var ids = new HashSet<uint256>();
foreach (Transaction tx in block.Transactions)
{
if (enforceBIP30)
{
uint256 txId = tx.GetHash();
ids.Add(txId);
}
if (tx.IsCoinBase) continue;
foreach (TxIn input in tx.Inputs.RemoveChangePointer())
{
ids.Add(input.PrevOut.Hash);
}
}
uint256[] res = ids.ToArray();
this.Logger.LogTrace("(-):*.{0}={1}", nameof(res.Length), res.Length);
return res;
}
} }
} }
\ 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