public void TrySetCoins(FetchCoinsResponse coins) { _Unspents = new Dictionary<uint256, UnspentOutputs>(coins.UnspentOutputs.Length); foreach (var coin in coins.UnspentOutputs) { if (coin != null) _Unspents.TryAdd(coin.TransactionId, coin); } }
public override async Task <FetchCoinsResponse> FetchCoinsAsync(uint256[] txIds) { Guard.NotNull(txIds, nameof(txIds)); FetchCoinsResponse result = null; uint256 innerBlockHash = null; UnspentOutputs[] outputs = new UnspentOutputs[txIds.Length]; List <int> miss = new List <int>(); List <uint256> missedTxIds = new List <uint256>(); using (_Lock.LockRead()) { WaitOngoingTasks(); for (int i = 0; i < txIds.Length; i++) { CacheItem cache; if (!_Unspents.TryGetValue(txIds[i], out cache)) { miss.Add(i); missedTxIds.Add(txIds[i]); } else { outputs[i] = cache.UnspentOutputs == null ? null : cache.UnspentOutputs.IsPrunable ? null : cache.UnspentOutputs.Clone(); } } PerformanceCounter.AddMissCount(miss.Count); PerformanceCounter.AddHitCount(txIds.Length - miss.Count); } var fetchedCoins = await Inner.FetchCoinsAsync(missedTxIds.ToArray()).ConfigureAwait(false); using (_Lock.LockWrite()) { _Flushing.Wait(); innerBlockHash = fetchedCoins.BlockHash; if (_BlockHash == null) { Debug.Assert(_Unspents.Count == 0); _InnerBlockHash = innerBlockHash; _BlockHash = innerBlockHash; } for (int i = 0; i < miss.Count; i++) { var index = miss[i]; var unspent = fetchedCoins.UnspentOutputs[i]; outputs[index] = unspent; CacheItem cache = new CacheItem(); cache.ExistInInner = unspent != null; cache.IsDirty = false; cache.UnspentOutputs = unspent; cache.OriginalOutputs = unspent?._Outputs.ToArray(); _Unspents.TryAdd(txIds[index], cache); } result = new FetchCoinsResponse(outputs, _BlockHash); } if (CacheEntryCount > MaxItems) { Evict(); if (CacheEntryCount > MaxItems) { await FlushAsync().ConfigureAwait(false); Evict(); } } return(result); }