Test the real function
MODIFY
WalletWasabi.Tests/RegTests.cs
WalletWasabi.Tests/RegTests.cs
@@ -342,7 +342,9 @@ namespace WalletWasabi.Tests
Assert.Equal(blockCount + 10, bitcoinStore.HashChain.HashCount);
// Test filter block hashes are correct.
- var filters = (await bitcoinStore.IndexStore.GetFiltersAsync(new Height(0), Height.MemPool, CancellationToken.None)).ToArray();
+ var filterList = new List<FilterModel>();
+ await bitcoinStore.IndexStore.ForeachFiltersAsync(x => filterList.Add(x), new Height(0));
+ FilterModel[] filters = filterList.ToArray();
for (int i = 0; i < 101; i++)
{
var expectedHash = await rpc.GetBlockHashAsync(i);
@@ -424,12 +426,18 @@ namespace WalletWasabi.Tests
tip = await rpc.GetBestBlockHashAsync();
Assert.Equal(tip, bitcoinStore.HashChain.TipHash);
- var filterTip = (await bitcoinStore.IndexStore.GetFiltersAsync(new Height(0), Height.MemPool, CancellationToken.None)).Last();
+
+ var filterList = new List<FilterModel>();
+ await bitcoinStore.IndexStore.ForeachFiltersAsync(x => filterList.Add(x), new Height(0));
+ var filterTip = filterList.Last();
Assert.Equal(tip, filterTip.BlockHash);
// Test filter block hashes are correct after fork.
var blockCountIncludingGenesis = await rpc.GetBlockCountAsync() + 1;
- var filters = (await bitcoinStore.IndexStore.GetFiltersAsync(new Height(0), new Height(blockCountIncludingGenesis - 1), CancellationToken.None)).ToArray();
+
+ filterList.Clear();
+ await bitcoinStore.IndexStore.ForeachFiltersAsync(x => filterList.Add(x), new Height(0));
+ FilterModel[] filters = filterList.ToArray();
for (int i = 0; i < blockCountIncludingGenesis; i++)
{
var expectedHash = await rpc.GetBlockHashAsync(i);

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -277,13 +277,13 @@ namespace WalletWasabi.Services
}
// Go through the filters and que to download the matches.
- await BitcoinStore.IndexStore.UseFilterModelsAsync(async (filterModel, c) =>
+ await BitcoinStore.IndexStore.ForeachFiltersAsync(async (filterModel) =>
{
- if (filterModel.Filter != null && filterModel.BlockHeight > bestKeyManagerHeight) // Filter can be null if there is no bech32 tx.
+ if (filterModel.Filter != null) // Filter can be null if there is no bech32 tx.
{
- await ProcessFilterModelAsync(filterModel, c);
+ await ProcessFilterModelAsync(filterModel, cancel);
}
- }, cancel);
+ }, new Height(bestKeyManagerHeight.Value + 1));
// Load in dummy mempool
if (File.Exists(TransactionsFilePath))

MODIFY
WalletWasabi/Stores/IndexStore.cs
WalletWasabi/Stores/IndexStore.cs
@@ -256,26 +256,17 @@ namespace WalletWasabi.Stores
}
}
- public async Task<IEnumerable<FilterModel>> GetFiltersAsync(Height from, Height to, CancellationToken cancel)
+ public async Task ForeachFiltersAsync(Action<FilterModel> todo, Height fromHeight)
{
- 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
+ using (await MatureIndexFileManager.Mutex.LockAsync())
+ using (await IndexLock.LockAsync())
{
- ret = new List<FilterModel>();
- Height height = StartingHeight;
var firstImmatureHeight = ImmatureFilters.FirstOrDefault()?.BlockHeight;
-
- using (await MatureIndexFileManager.Mutex.LockAsync(cancel))
+ if (!firstImmatureHeight.HasValue || firstImmatureHeight.Value > fromHeight)
{
if (MatureIndexFileManager.Exists())
{
+ Height height = StartingHeight;
using (var sr = MatureIndexFileManager.OpenText(16384))
{
while (!sr.EndOfStream)
@@ -287,65 +278,24 @@ namespace WalletWasabi.Stores
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)
+ if (height < fromHeight.Value)
{
- ret.Add(filter);
- }
-
height++;
-
- cancel.ThrowIfCancellationRequested();
- }
- }
- }
-
- foreach (FilterModel filter in ImmatureFilters)
- {
- ret.Add(filter);
- }
- }
- }
- }
-
- return ret;
- }
-
- public async Task UseFilterModelsAsync(Action<FilterModel, CancellationToken> todo, CancellationToken cancel)
- {
- using (await MatureIndexFileManager.Mutex.LockAsync(cancel))
- using (await IndexLock.LockAsync(cancel))
- {
- Height height = StartingHeight;
- var firstImmatureHeight = ImmatureFilters.FirstOrDefault()?.BlockHeight;
-
- if (MatureIndexFileManager.Exists())
- {
- using (var sr = MatureIndexFileManager.OpenText(16384))
- {
- while (!sr.EndOfStream)
- {
- var line = await sr.ReadLineAsync();
-
- if (firstImmatureHeight == height)
- {
- break; // Let's use our the immature filters from here on. The content is the same, just someone else modified the file.
+ continue;
}
var filter = FilterModel.FromHeightlessLine(line, height);
- todo(filter, cancel);
+ todo(filter);
height++;
-
- cancel.ThrowIfCancellationRequested();
+ }
}
}
}
foreach (FilterModel filter in ImmatureFilters)
{
- todo(filter, cancel);
+ todo(filter);
}
}
}

Test the real function