Пример #1
0
        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);
        }
Пример #2
0
        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();
            }
        }
Пример #3
0
        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;
            }
        }
Пример #4
0
 public bool LockAccount(Address address)
 {
     AccountLocked?.Invoke(this, new AccountLockedEventArgs(address));
     _unlockedAccounts.Delete(address.ToString());
     return(true);
 }