Commit f61773fd authored by Sergei Zubov's avatar Sergei Zubov

Merge load coinview rule

parent 775402e3
......@@ -115,7 +115,7 @@ namespace Stratis.Bitcoin.Features.Consensus
new SetActivationDeploymentsFullValidationRule(),
// rules that require the store to be loaded (coinview)
new LoadCoinviewRule(),
new DeStreamLoadCoinviewRule(),
new TransactionDuplicationActivationRule(), // implements BIP30
new DeStreamPowCoinviewRule(), // implements BIP68, MaxSigOps and BlockReward calculation
new SaveCoinviewRule(),
......@@ -173,7 +173,7 @@ namespace Stratis.Bitcoin.Features.Consensus
new CheckDifficultyHybridRule(),
// rules that require the store to be loaded (coinview)
new LoadCoinviewRule(),
new DeStreamLoadCoinviewRule(),
new TransactionDuplicationActivationRule(), // implements BIP30
new DeStreamPosCoinviewRule(), // implements BIP68, MaxSigOps and BlockReward calculation
// Place the PosColdStakingRule after the PosCoinviewRule to ensure that all input scripts have been evaluated
......
......@@ -4,74 +4,48 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using NBitcoin;
using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.Consensus.Rules;
using Stratis.Bitcoin.Features.Consensus.CoinViews;
using Stratis.Bitcoin.Utilities;
namespace Stratis.Bitcoin.Features.Consensus.Rules.CommonRules
{
[ExecutionRule]
public class DeStreamLoadCoinviewRule : LoadCoinviewRule
{
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.
// The UTXO set is stored in the context.
this.Logger.LogTrace("Loading UTXO set of the new block.");
utxoRuleContext.UnspentOutputSet = new DeStreamUnspentOutputSet();
var utxoRuleContext = context as UtxoRuleContext;
switch (utxoRuleContext)
{
case DeStreamPowRuleContext deStreamPowRuleContext:
deStreamPowRuleContext.InputScriptPubKeys = new Dictionary<uint256, List<Script>>();
break;
case DeStreamRuleContext deStreamPosRuleContext:
case DeStreamPosRuleContext deStreamPosRuleContext:
deStreamPosRuleContext.InputScriptPubKeys = new Dictionary<uint256, List<Script>>();
break;
default:
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)))
{
uint256[] ids = this.GetIdsToFetch(context.ValidationContext.Block, context.Flags.EnforceBIP30);
// 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.
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);
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