Write basic initialize function to IndexStore
DELETE
WalletWasabi.Tests/BitcoinStoreTests.cs
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace WalletWasabi.Tests
-{
- public class BitcoinStoreTests
- {
- }
-}

ADD
WalletWasabi.Tests/StoreTests.cs
+using NBitcoin;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using WalletWasabi.Stores;
+using Xunit;
+
+namespace WalletWasabi.Tests
+{
+ public class StoreTests
+ {
+ [Fact]
+ public async Task IndexStoreTestsAsync()
+ {
+ var indexStore = new IndexStore();
+
+ var dir = Path.Combine(Global.DataDir, nameof(IndexStoreTestsAsync));
+ var network = Network.Main;
+ await indexStore.InitializeAsync(dir, network);
+ }
+ }
+}

ADD
WalletWasabi/Stores/IndexStore.cs
+using NBitcoin;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WalletWasabi.Backend.Models;
+using WalletWasabi.Helpers;
+using WalletWasabi.Models;
+using WalletWasabi.Services;
+
+namespace WalletWasabi.Stores
+{
+ /// <summary>
+ /// Manages to store the filters safely.
+ /// </summary>
+ public class IndexStore
+ {
+ private const string IndexFileName = "Index.dat";
+ private string WorkFolderPath { get; set; }
+ private Network Network { get; set; }
+ private string IndexFilePath { get; set; }
+
+ private FilterModel StartingFilter { get; set; }
+ private Height StartingHeight { get; set; }
+
+ private object IndexLock { get; set; }
+ private List<FilterModel> Index { get; set; }
+
+ public async Task InitializeAsync(string workFolderPath, Network network)
+ {
+ WorkFolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(workFolderPath), workFolderPath, trim: true);
+ Network = Guard.NotNull(nameof(network), network);
+ IndexFilePath = Path.Combine(WorkFolderPath, IndexFileName);
+
+ StartingFilter = StartingFilters.GetStartingFilter(Network);
+ StartingHeight = StartingFilters.GetStartingHeight(Network);
+
+ Index = new List<FilterModel>();
+
+ IoHelpers.EnsureDirectoryExists(WorkFolderPath);
+
+ if (Network == Network.RegTest)
+ {
+ IoHelpers.BetterDelete(IndexFilePath); // RegTest is not a global ledger, better to delete it.
+ }
+
+ if (!File.Exists(IndexFilePath))
+ {
+ Index.Add(StartingFilter);
+ await File.WriteAllLinesAsync(IndexFilePath, Index.Select(x => x.ToHeightlessLine()));
+ }
+
+ var height = StartingHeight;
+ try
+ {
+ foreach (var line in await File.ReadAllLinesAsync(IndexFilePath))
+ {
+ var filter = FilterModel.FromHeightlessLine(line, height);
+ height++;
+ Index.Add(filter);
+ }
+ }
+ catch (FormatException)
+ {
+ // We found a corrupted entry. Stop here.
+ // Fix the currupted file.
+ await File.WriteAllLinesAsync(IndexFilePath, Index.Select(x => x.ToHeightlessLine()));
+ }
+ }
+ }
+}

ADD
WalletWasabi/Stores/StartingFilters.cs
+using NBitcoin;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using WalletWasabi.Backend.Models;
+using WalletWasabi.Models;
+
+namespace WalletWasabi.Stores
+{
+ public static class StartingFilters
+ {
+ public static FilterModel GetStartingFilter(Network network)
+ {
+ if (network == Network.Main)
+ {
+ return FilterModel.FromHeightlessLine("0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893:02832810ec08a0", GetStartingHeight(network));
+ }
+ if (network == Network.TestNet)
+ {
+ return FilterModel.FromHeightlessLine("00000000000f0d5edcaeba823db17f366be49a80d91d15b77747c2e017b8c20a:017821b8", GetStartingHeight(network));
+ }
+ if (network == Network.RegTest)
+ {
+ return FilterModel.FromHeightlessLine("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206", GetStartingHeight(network));
+ }
+ throw new NotSupportedException($"{network} is not supported.");
+ }
+
+ public static Height GetStartingHeight(Network network) // First possible bech32 transaction ever.
+ {
+ if (network == Network.Main)
+ {
+ return new Height(481824);
+ }
+ if (network == Network.TestNet)
+ {
+ return new Height(828575);
+ }
+ if (network == Network.RegTest)
+ {
+ return new Height(0);
+ }
+ throw new NotSupportedException($"{network} is not supported.");
+ }
+ }
+}

Write basic initialize function to IndexStore