Enable uncommented tests
MODIFY
WalletWasabi.Tests/RegTests.cs
WalletWasabi.Tests/RegTests.cs
@@ -342,15 +342,15 @@ namespace WalletWasabi.Tests
Assert.Equal(blockCount + 10, bitcoinStore.HashChain.HashCount);
// Test filter block hashes are correct.
- //var filters = (await bitcoinStore.IndexStore.GetFiltersAsync()).ToArray();
- //for (int i = 0; i < 101; i++)
- //{
- // var expectedHash = await rpc.GetBlockHashAsync(i);
- // var filter = filters[i];
- // Assert.Equal(i, filter.BlockHeight.Value);
- // Assert.Equal(expectedHash, filter.BlockHash);
- // Assert.Null(filter.Filter);
- //}
+ var filters = (await bitcoinStore.IndexStore.GetFiltersAsync(new Height(0), Height.MemPool, CancellationToken.None)).ToArray();
+ for (int i = 0; i < 101; i++)
+ {
+ var expectedHash = await rpc.GetBlockHashAsync(i);
+ var filter = filters[i];
+ Assert.Equal(i, filter.BlockHeight.Value);
+ Assert.Equal(expectedHash, filter.BlockHash);
+ Assert.Null(filter.Filter);
+ }
}
}
@@ -422,20 +422,25 @@ namespace WalletWasabi.Tests
Assert.DoesNotContain(tip, hashes);
Assert.DoesNotContain(tipBlock.HashPrevBlock, hashes);
+ tip = await rpc.GetBestBlockHashAsync();
+ Assert.Equal(tip, bitcoinStore.HashChain.TipHash);
+ var filterTip = (await bitcoinStore.IndexStore.GetFiltersAsync(new Height(0), Height.MemPool, CancellationToken.None)).Last();
+ Assert.Equal(tip, filterTip.BlockHash);
+
// Test filter block hashes are correct after fork.
- //var filters = (await bitcoinStore.IndexStore.GetFiltersAsync()).ToArray();
- //var blockCountIncludingGenesis = await rpc.GetBlockCountAsync() + 1;
- //for (int i = 0; i < blockCountIncludingGenesis; i++)
- //{
- // var expectedHash = await rpc.GetBlockHashAsync(i);
- // var filter = filters[i];
- // Assert.Equal(i, filter.BlockHeight.Value);
- // Assert.Equal(expectedHash, filter.BlockHash);
- // if (i < 101) // Later other tests may fill the filter.
- // {
- // Assert.Null(filter.Filter);
- // }
- //}
+ var filters = (await bitcoinStore.IndexStore.GetFiltersAsync(new Height(0), Height.MemPool, CancellationToken.None)).ToArray();
+ var blockCountIncludingGenesis = await rpc.GetBlockCountAsync() + 1;
+ for (int i = 0; i < blockCountIncludingGenesis; i++)
+ {
+ var expectedHash = await rpc.GetBlockHashAsync(i);
+ var filter = filters[i];
+ Assert.Equal(i, filter.BlockHeight.Value);
+ Assert.Equal(expectedHash, filter.BlockHash);
+ if (i < 101) // Later other tests may fill the filter.
+ {
+ Assert.Null(filter.Filter);
+ }
+ }
// Test the serialization, too.
tip = await rpc.GetBestBlockHashAsync();

MODIFY
WalletWasabi.Tests/StoreTests.cs
WalletWasabi.Tests/StoreTests.cs
@@ -22,7 +22,7 @@ namespace WalletWasabi.Tests
var dir = Path.Combine(Global.DataDir, nameof(IndexStoreTestsAsync));
var network = Network.Main;
- await indexStore.InitializeAsync(dir, network);
+ await indexStore.InitializeAsync(dir, network, new HashChain());
}
[Fact]

MODIFY
WalletWasabi/Helpers/ByteHelpers.cs
WalletWasabi/Helpers/ByteHelpers.cs
@@ -170,13 +170,5 @@ namespace System
return bytes;
}
-
- public static byte[] GetHash(byte[] bytes)
- {
- using (var sha = new SHA256Managed())
- {
- return sha.ComputeHash(bytes, 0, bytes.Length);
- }
- }
}
}

MODIFY
WalletWasabi/Helpers/IoHelpers.cs
WalletWasabi/Helpers/IoHelpers.cs
@@ -95,7 +95,7 @@ namespace System.IO
public static byte[] GetHashFile(string filePath)
{
var bytes = File.ReadAllBytes(filePath);
- return ByteHelpers.GetHash(bytes);
+ return HashHelpers.GenerateSha256Hash(bytes);
}
public static bool CheckExpectedHash(string filePath, string sourceFolderPath)

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -277,7 +277,7 @@ namespace WalletWasabi.Services
}
// Go through the filters and que to download the matches.
- await BitcoinStore.IndexStore.UseLinesAsync(async (filterModel, c) =>
+ await BitcoinStore.IndexStore.UseFilterModelsAsync(async (filterModel, c) =>
{
if (filterModel.Filter != null && filterModel.BlockHeight > bestKeyManagerHeight) // Filter can be null if there is no bech32 tx.
{

MODIFY
WalletWasabi/Stores/BitcoinStore.cs
WalletWasabi/Stores/BitcoinStore.cs
@@ -29,8 +29,8 @@ namespace WalletWasabi.Stores
IndexStore = new IndexStore();
var indexStoreFolderPath = Path.Combine(WorkFolderPath, Network.ToString());
- await IndexStore.InitializeAsync(indexStoreFolderPath, Network);
- HashChain = IndexStore.HashChain;
+ HashChain = new HashChain();
+ await IndexStore.InitializeAsync(indexStoreFolderPath, Network, HashChain);
}
}
}

MODIFY
WalletWasabi/Stores/IndexStore.cs
WalletWasabi/Stores/IndexStore.cs
@@ -35,11 +35,11 @@ namespace WalletWasabi.Stores
public event EventHandler<FilterModel> NewFilter;
- public async Task InitializeAsync(string workFolderPath, Network network)
+ public async Task InitializeAsync(string workFolderPath, Network network, HashChain hashChain)
{
WorkFolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(workFolderPath), workFolderPath, trim: true);
-
Network = Guard.NotNull(nameof(network), network);
+ HashChain = Guard.NotNull(nameof(hashChain), hashChain);
var indexFilePath = Path.Combine(WorkFolderPath, "MatureIndex.dat");
MatureIndexFileManager = new IoManager(indexFilePath, digestRandomIndex: -1);
var immatureIndexFilePath = Path.Combine(WorkFolderPath, "ImmatureIndex.dat");
@@ -49,7 +49,6 @@ namespace WalletWasabi.Stores
StartingHeight = StartingFilters.GetStartingHeight(Network);
ImmatureFilters = new List<FilterModel>(150);
- HashChain = new HashChain();
IndexLock = new AsyncLock();
@@ -249,18 +248,63 @@ namespace WalletWasabi.Stores
}
}
- //public async Task<IEnumerable<FilterModel>> GetFiltersAsync()
- //{
- // List<FilterModel> ret = null;
+ public async Task<IEnumerable<FilterModel>> GetFiltersAsync(Height from, Height to, CancellationToken cancel)
+ {
+ List<FilterModel> ret = null;
+
+ using (await IndexLock.LockAsync(cancel))
+ {
+ if (ImmatureFilters.Any(x => x.BlockHeight == from))
+ {
+ ret = ImmatureFilters.Where(x => x.BlockHeight >= from && x.BlockHeight <= to).ToList();
+ }
+ else
+ {
+ ret = new List<FilterModel>();
+ Height height = StartingHeight;
+ var firstImmatureLine = ImmatureFilters.FirstOrDefault()?.ToHeightlessLine();
+
+ using (await MatureIndexFileManager.Mutex.LockAsync(cancel))
+ {
+ if (MatureIndexFileManager.Exists())
+ {
+ using (var sr = MatureIndexFileManager.OpenText(16384))
+ {
+ while (!sr.EndOfStream)
+ {
+ var line = await sr.ReadLineAsync();
+
+ if (firstImmatureLine == line)
+ {
+ break; // Let's use our the immature filters from here on. The content is the same, just someone else modified the file.
+ }
+
+ var filter = FilterModel.FromHeightlessLine(line, height);
+
+ if (filter.BlockHeight >= from && filter.BlockHeight <= to)
+ {
+ ret.Add(filter);
+ }
+
+ height++;
- // using (await IndexLock.LockAsync())
- // {
- // ret = Index.ToList();
- // }
- // return ret;
- //}
+ cancel.ThrowIfCancellationRequested();
+ }
+ }
+ }
+
+ foreach (FilterModel filter in ImmatureFilters)
+ {
+ ret.Add(filter);
+ }
+ }
+ }
+ }
+
+ return ret;
+ }
- public async Task UseLinesAsync(Action<FilterModel, CancellationToken> todo, CancellationToken cancel)
+ public async Task UseFilterModelsAsync(Action<FilterModel, CancellationToken> todo, CancellationToken cancel)
{
using (await MatureIndexFileManager.Mutex.LockAsync(cancel))
using (await IndexLock.LockAsync(cancel))

MODIFY
WalletWasabi/Stores/IoManager.cs
WalletWasabi/Stores/IoManager.cs
@@ -44,6 +44,7 @@ namespace WalletWasabi.Stores
DigestFilePath = $"{OriginalFilePath}{DigestExtension}";
FileName = Path.GetFileName(OriginalFilePath);
+ var shortHash = HashHelpers.GenerateSha256Hash(OriginalFilePath).Take(7);
FileNameWithoutExtension = Path.GetFileNameWithoutExtension(OriginalFilePath);
// https://docs.microsoft.com/en-us/dotnet/api/system.threading.mutex?view=netframework-4.8
@@ -55,7 +56,7 @@ namespace WalletWasabi.Stores
// Within a terminal server session, two mutexes whose names differ only by their prefixes are separate mutexes,
// and both are visible to all processes in the terminal server session.
// That is, the prefix names "Global\" and "Local\" describe the scope of the mutex name relative to terminal server sessions, not relative to processes.
- Mutex = new AsyncMutex(FileNameWithoutExtension);
+ Mutex = new AsyncMutex($"{FileNameWithoutExtension}-{shortHash}");
}
#region IoOperations
@@ -196,7 +197,7 @@ namespace WalletWasabi.Stores
bytes = byteArrayBuilder.ToArray();
- hash = ByteHelpers.GetHash(bytes);
+ hash = HashHelpers.GenerateSha256Hash(bytes);
if (File.Exists(DigestFilePath))
{
var digest = await File.ReadAllBytesAsync(DigestFilePath, cancellationToken);
@@ -350,7 +351,7 @@ namespace WalletWasabi.Stores
try
{
- hash = ByteHelpers.GetHash(bytes);
+ hash = HashHelpers.GenerateSha256Hash(bytes);
if (File.Exists(DigestFilePath))
{
var digest = await File.ReadAllBytesAsync(DigestFilePath, cancellationToken);

Enable uncommented tests