private IEthashDataSet GetOrAddCache(uint epoch) { DataSetWithAccessTime theOne; lock (_cacheCache) { for (uint i = Math.Max(epoch, 2) - 2; i < epoch + 3; i++) { if (_cacheCache.Get(i) == default) { DataSetWithAccessTime someone = new DataSetWithAccessTime(i, BuildCache(i), Timestamper.Default.EpochSeconds); _cacheCache.Set(i, someone); _cacheMonitor.Add(someone); } } var now = Timestamper.Default.EpochSeconds; theOne = _cacheCache.Get(epoch); theOne.AccessTime = now; HashSet <DataSetWithAccessTime> removed = null; foreach (DataSetWithAccessTime dataSetWithAccessTime in _cacheMonitor) { if (now - dataSetWithAccessTime.AccessTime > 15) { _cacheCache.Delete(dataSetWithAccessTime.Epoch); if (removed == null) { removed = new HashSet <DataSetWithAccessTime>(); } removed.Add(dataSetWithAccessTime); } } if (removed != null) { foreach (DataSetWithAccessTime dataSetWithAccessTime in removed) { _cacheMonitor.Remove(dataSetWithAccessTime); dataSetWithAccessTime.DataSet.Result.Dispose(); } } } IEthashDataSet dataSet = theOne.DataSet.Result; return(dataSet); }
public void Delete(long number, BatchWrite batch = null) { void Delete() { _blockInfoCache.Delete(number); _blockInfoDb.Delete(number); } bool needLock = batch?.Disposed != false; if (needLock) { lock (_writeLock) { Delete(); } } else { Delete(); } }
private void CleanInvalidBlocks(Keccak deletePointer) { BlockHeader deleteHeader = FindHeader(deletePointer); long currentNumber = deleteHeader.Number; Keccak currentHash = deleteHeader.Hash; Keccak nextHash = null; ChainLevelInfo nextLevel = null; while (true) { ChainLevelInfo currentLevel = nextLevel ?? LoadLevel(currentNumber); nextLevel = LoadLevel(currentNumber + 1); bool shouldRemoveLevel = false; if (currentLevel != null) // preparing update of the level (removal of the invalid branch block) { if (currentLevel.BlockInfos.Length == 1) { shouldRemoveLevel = true; } else { for (int i = 0; i < currentLevel.BlockInfos.Length; i++) { if (currentLevel.BlockInfos[0].BlockHash == currentHash) { currentLevel.BlockInfos = currentLevel.BlockInfos.Where(bi => bi.BlockHash != currentHash).ToArray(); break; } } } } if (nextLevel != null) // just finding what the next descendant will be { if (nextLevel.BlockInfos.Length == 1) { nextHash = nextLevel.BlockInfos[0].BlockHash; } else { for (int i = 0; i < nextLevel.BlockInfos.Length; i++) { BlockHeader potentialDescendant = FindHeader(nextLevel.BlockInfos[i].BlockHash); if (potentialDescendant.ParentHash == currentHash) { nextHash = potentialDescendant.Hash; break; } } } UpdateDeletePointer(nextHash); } else { UpdateDeletePointer(null); } try { _blockInfoLock.EnterWriteLock(); if (shouldRemoveLevel) { BestKnownNumber = Math.Min(BestKnownNumber, currentNumber - 1); _blockInfoCache.Delete(currentNumber); _blockInfoDb.Delete(currentNumber); } else { PersistLevel(currentNumber, currentLevel); } } finally { _blockInfoLock.ExitWriteLock(); } if (_logger.IsInfo) { _logger.Info($"Deleting invalid block {currentHash} at level {currentNumber}"); } _blockCache.Delete(currentHash); _blockDb.Delete(currentHash); _headerCache.Delete(currentHash); _headerDb.Delete(currentHash); if (nextHash == null) { break; } currentNumber++; currentHash = nextHash; nextHash = null; } }
public bool LockAccount(Address address) { AccountLocked?.Invoke(this, new AccountLockedEventArgs(address)); _unlockedAccounts.Delete(address.ToString()); return(true); }