public ContextInformation(BlockResult blockResult, NBitcoin.Consensus consensus) { Guard.NotNull(blockResult, nameof(blockResult)); Guard.NotNull(consensus, nameof(consensus)); this.BlockResult = blockResult; this.Consensus = consensus; // TODO: adding flags to determine the flow of logic is not ideal // a refator is in depbate on moving to a consensus rules engine // this will remove hte need for flags as a validation will // only use the required rules (i.e if the check pow rule will be ommited form the flow) this.CheckPow = true; this.CheckMerkleRoot = true; this.OnlyCheck = false; }
public void AcceptBlock(BlockResult result) { ContextInformation context; ConsensusFlags flags; using (watch.Start(o => Validator.PerformanceCounter.AddBlockProcessingTime(o))) { Validator.CheckBlockHeader(result.Block.Header); if (result.Block.Header.HashPrevBlock != Tip.HashBlock) { return; // reorg } result.ChainedBlock = new ChainedBlock(result.Block.Header, result.Block.Header.GetHash(), Tip); result.ChainedBlock = Chain.GetBlock(result.ChainedBlock.HashBlock) ?? result.ChainedBlock; //Liberate from memory the block created above if possible context = new ContextInformation(result.ChainedBlock, Validator.ConsensusParams); Validator.ContextualCheckBlockHeader(result.Block.Header, context); flags = GetFlags(result.ChainedBlock); Validator.ContextualCheckBlock(result.Block, flags, context); Validator.CheckBlock(result.Block); } var set = new UnspentOutputSet(); using (watch.Start(o => Validator.PerformanceCounter.AddUTXOFetchingTime(o))) { var ids = GetIdsToFetch(result.Block, flags.EnforceBIP30); var coins = UTXOSet.FetchCoinsAsync(ids).GetAwaiter().GetResult(); set.SetCoins(coins); } TryPrefetchAsync(flags); using (watch.Start(o => Validator.PerformanceCounter.AddBlockProcessingTime(o))) { Validator.ExecuteBlock(result.Block, result.ChainedBlock, flags, set, null); } UTXOSet.SaveChangesAsync(set.GetCoins(UTXOSet), null, Tip.HashBlock, result.ChainedBlock.HashBlock); _Tip = result.ChainedBlock; }
public BlockResult ExecuteNextBlock(CancellationToken cancellationToken) { BlockResult result = new BlockResult(); try { using (watch.Start(o => Validator.PerformanceCounter.AddBlockFetchingTime(o))) { while (true) { result.Block = Puller.NextBlock(cancellationToken); if (result.Block != null) { break; } else { while (true) { var hash = UTXOSet.Rewind().GetAwaiter().GetResult(); var rewinded = Chain.GetBlock(hash); if (rewinded == null) { continue; } _Tip = rewinded; Puller.SetLocation(rewinded); break; } } } } this.AcceptBlock(result); } catch (ConsensusErrorException ex) { result.Error = ex.ConsensusError; } return(result); }