public StateSyncFeed( ISnapshotableDb codeDb, ISnapshotableDb stateDb, IDb tempDb, ISyncModeSelector syncModeSelector, IBlockTree blockTree, ILogManager logManager) { _codeDb = codeDb?.Innermost ?? throw new ArgumentNullException(nameof(codeDb)); _stateDb = stateDb?.Innermost ?? throw new ArgumentNullException(nameof(stateDb)); _tempDb = tempDb ?? throw new ArgumentNullException(nameof(tempDb)); _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); _syncModeSelector = syncModeSelector ?? throw new ArgumentNullException(nameof(syncModeSelector)); _syncModeSelector.Changed += SyncModeSelectorOnChanged; _logger = logManager.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); byte[] progress = _codeDb.Get(_fastSyncProgressKey); _data = new DetailedProgress(_blockTree.ChainId, progress); _pendingItems = new PendingSyncItems(); _syncProgress = new StateSyncProgress(0, _logger); }
public void ResetStateRoot(long blockNumber, Keccak stateRoot) { if (CurrentState != SyncFeedState.Dormant) { throw new InvalidOperationException("Cannot reset state sync on an active feed"); } Interlocked.Exchange(ref _hintsToResetRoot, 0); if (_logger.IsInfo) { _logger.Info($"Setting state sync state root to {blockNumber} {stateRoot}"); } _currentSyncStart = DateTime.UtcNow; _currentSyncStartSecondsInSync = _data.SecondsInSync; _data.LastReportTime = (DateTime.UtcNow, DateTime.UtcNow); _data.LastSavedNodesCount = _data.SavedNodesCount; _data.LastRequestedNodesCount = _data.RequestedNodesCount; if (_rootNode != stateRoot) { _syncProgress = new StateSyncProgress(blockNumber, _logger); _blockNumber = blockNumber; _rootNode = stateRoot; lock (_dependencies) _dependencies.Clear(); lock (_codesSameAsNodes) _codesSameAsNodes.Clear(); _pendingItems.Clear(); if (_logger.IsDebug) { _logger.Debug($"Clearing node stacks ({_pendingItems.Description})"); } } else { foreach ((StateSyncBatch pendingRequest, _) in _pendingRequests) { // re-add the pending request for (int i = 0; i < pendingRequest.RequestedNodes.Length; i++) { AddNodeToPending(pendingRequest.RequestedNodes[i], null, "pending request", true); } } } _pendingRequests.Clear(); bool hasOnlyRootNode = false; if (_rootNode != Keccak.EmptyTreeHash) { if (_pendingItems.Count == 1) { // state root can only be located on state stream StateSyncItem potentialRoot = _pendingItems.PeekState(); if (potentialRoot?.Hash == _rootNode) { hasOnlyRootNode = true; } } if (!hasOnlyRootNode) { AddNodeToPending(new StateSyncItem(_rootNode, NodeDataType.State, 0, 0), null, "initial"); } } }