private Task FlushAsync() { _InnerCommitable.Clear(); _Commitable.Commit(); _Commitable.Clear(); var t = Task.Run(() => { _InnerCommitable.Commit(); _LastFlush = DateTimeOffset.UtcNow; }); _Commiting = t; return(t); }
/// <summary> /// Pull blocks, validate them and update the UTXO Set /// </summary> /// <param name="utxo">UTXO Set</param> /// <param name="puller">Block source</param> /// <returns>Stream of validated blocks</returns> public IEnumerable <Block> Run(CoinViewStack utxoStack, BlockPuller puller) { var utxo = utxoStack.Top; var cache = utxoStack.Find <CacheCoinView>(); var lookaheadPuller = puller as ILookaheadBlockPuller; puller.SetLocation(utxo.Tip); ThresholdConditionCache bip9 = new ThresholdConditionCache(_ConsensusParams); StopWatch watch = new StopWatch(); bool rejected = false; while (true) { Block block = null; while (true) { rejected = false; try { using (watch.Start(o => PerformanceCounter.AddBlockFetchingTime(o))) { block = puller.NextBlock(); } ChainedBlock next; ContextInformation context; ConsensusFlags flags; using (watch.Start(o => PerformanceCounter.AddBlockProcessingTime(o))) { CheckBlockHeader(block.Header); next = new ChainedBlock(block.Header, block.Header.GetHash(), utxo.Tip); context = new ContextInformation(next, this._ConsensusParams); ContextualCheckBlockHeader(block.Header, context); var states = bip9.GetStates(utxo.Tip); flags = new ConsensusFlags(next, states, _ConsensusParams); ContextualCheckBlock(block, flags, context); CheckBlock(block); } var commitable = new CommitableCoinView(next, utxo); using (watch.Start(o => PerformanceCounter.AddUTXOFetchingTime(o))) { commitable.FetchCoins(GetIdsToFetch(block, flags.EnforceBIP30)); } commitable.SetInner(NullCoinView.Instance); Task prefetching = GetPrefetchingTask(cache, lookaheadPuller, flags); using (watch.Start(o => PerformanceCounter.AddBlockProcessingTime(o))) { ExecuteBlock(block, next, flags, commitable, null); } using (watch.Start(o => PerformanceCounter.AddUTXOFetchingTime(o))) { prefetching.Wait(); commitable.Commit(utxo); } } catch (ConsensusErrorException ex) { rejected = true; if (ex.ConsensusError == ConsensusErrors.TimeTooNew) { puller.Reject(block, RejectionMode.Temporary); } else { puller.Reject(block, RejectionMode.Permanent); } } if (!rejected) { yield return(block); } } } }