private async Task TryEnsureBackwardsCompatibilityAsync() { try { // Before Wasabi 1.1.5 var oldIndexFilepath = Path.Combine(EnvironmentHelpers.GetDataDir(Path.Combine("WalletWasabi", "Client")), $"Index{Network}.dat"); if (File.Exists(oldIndexFilepath)) { string[] allLines = await File.ReadAllLinesAsync(oldIndexFilepath); var matureLines = allLines.SkipLast(100); var immatureLines = allLines.TakeLast(100); await MatureIndexFileManager.WriteAllLinesAsync(matureLines); await ImmatureIndexFileManager.WriteAllLinesAsync(immatureLines); File.Delete(oldIndexFilepath); } } catch (Exception ex) { Logger.LogWarning <IndexStore>($"Backwards compatibility couldn't be ensured. Exception: {ex.ToString()}"); } }
/// <summary> /// It'll LogError the exceptions. /// If cancelled, it'll LogTrace the exception. /// </summary> private async Task TryCommitToFileAsync(TimeSpan throttle, CancellationToken cancel) { try { // If throttle is requested, then throttle. if (throttle != TimeSpan.Zero) { // Increment the throttle ID and remember the incremented value. int incremented = Interlocked.Increment(ref _throttleId); if (incremented < 21) { await Task.Delay(throttle, cancel); } // If the _throttleId is still the incremented value, then I am the latest CommitToFileAsync request. // In this case I want to make the _throttledId 0 and go ahead and do the writeline. // If the _throttledId is not the incremented value anymore then I am not the latest request here, // So just return, the latest request will do the file write in its own time. if (Interlocked.CompareExchange(ref _throttleId, 0, incremented) != incremented) { return; } } else { Interlocked.Exchange(ref _throttleId, 0); // So to notified the currently throttled threads that they don't have to run. } using (await MatureIndexFileManager.Mutex.LockAsync(cancel)) using (await ImmatureIndexFileManager.Mutex.LockAsync(cancel)) using (await IndexLock.LockAsync(cancel)) { // Don't feed the cancellationToken here I always want this to finish running for safety. var currentImmatureLines = ImmatureFilters.Select(x => x.ToHeightlessLine()); var matureLinesToAppend = currentImmatureLines.SkipLast(100); var immatureLines = currentImmatureLines.TakeLast(100); await MatureIndexFileManager.AppendAllLinesAsync(matureLinesToAppend); await ImmatureIndexFileManager.WriteAllLinesAsync(immatureLines); while (ImmatureFilters.Count > 100) { ImmatureFilters.RemoveFirst(); } } } catch (Exception ex) when(ex is OperationCanceledException || ex is TaskCanceledException || ex is TimeoutException) { Logger.LogTrace <IndexStore>(ex); } catch (Exception ex) { Logger.LogError <IndexStore>(ex); } }
private async Task EnsureBackwardsCompatibilityAsync() { try { // Before Wasabi 1.1.5 var oldIndexFilePath = Path.Combine(EnvironmentHelpers.GetDataDir(Path.Combine("WalletWasabi", "Client")), $"Index{Network}.dat"); // Before Wasabi 1.1.6 var oldFileNames = new[] { "ImmatureIndex.dat", "ImmatureIndex.dat.dig", "MatureIndex.dat", "MatureIndex.dat.dig" }; var oldIndexFolderPath = Path.Combine(EnvironmentHelpers.GetDataDir(Path.Combine("WalletWasabi", "Client")), "BitcoinStore", Network.ToString()); foreach (var fileName in oldFileNames) { var oldFilePath = Path.Combine(oldIndexFolderPath, fileName); if (File.Exists(oldFilePath)) { string newFilePath = oldFilePath.Replace(oldIndexFolderPath, WorkFolderPath); if (File.Exists(newFilePath)) { File.Delete(newFilePath); } File.Move(oldFilePath, newFilePath); } } if (File.Exists(oldIndexFilePath)) { string[] allLines = await File.ReadAllLinesAsync(oldIndexFilePath).ConfigureAwait(false); var matureLines = allLines.SkipLast(100); var immatureLines = allLines.TakeLast(100); await MatureIndexFileManager.WriteAllLinesAsync(matureLines).ConfigureAwait(false); await ImmatureIndexFileManager.WriteAllLinesAsync(immatureLines).ConfigureAwait(false); File.Delete(oldIndexFilePath); } await DeleteIfDeprecatedAsync().ConfigureAwait(false); } catch (Exception ex) { Logger.LogWarning($"Backwards compatibility could not be ensured. Exception: {ex}."); } }