Add status request API
MODIFY
WalletWasabi.Backend/Controllers/BlockchainController.cs
WalletWasabi.Backend/Controllers/BlockchainController.cs
@@ -419,5 +419,33 @@ namespace WalletWasabi.Backend.Controllers
return feeResponse;
}
+
+ [HttpGet("status")]
+ [ProducesResponseType(typeof(StatusResponse), 200)]
+ [ResponseCache(Duration = 10, Location = ResponseCacheLocation.Client)]
+ public async Task<StatusResponse> GetStatusAsync()
+ {
+ var result = new StatusResponse();
+
+ try
+ {
+ var lastFilter = Global.IndexBuilderService.GetLastFilter();
+ var lastFilterHash = lastFilter.Header.BlockHash;
+
+ var bestHash = await RpcClient.GetBestBlockHashAsync();
+ var lastBlock = await RpcClient.GetBlockAsync(bestHash);
+ var prevHash = lastBlock.Header.HashPrevBlock;
+
+ if (bestHash == lastFilterHash || prevHash == lastFilterHash)
+ {
+ result.FilterCreationActive = true;
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.LogDebug(ex);
+ }
+ return result;
+ }
}
}

MODIFY
WalletWasabi.Tests/IntegrationTests/RegTests.cs
WalletWasabi.Tests/IntegrationTests/RegTests.cs
@@ -238,6 +238,68 @@ namespace WalletWasabi.Tests.IntegrationTests
}
}
+ [Fact]
+ public async Task StatusRequestTestAsync()
+ {
+ const string request = "/api/v3/btc/Blockchain/status";
+ (string password, RPCClient rpc, Network network, Coordinator coordinator, ServiceConfiguration serviceConfiguration, BitcoinStore bitcoinStore, Backend.Global global) = await InitializeTestEnvironmentAsync(1);
+
+ var indexBuilderService = global.IndexBuilderService;
+ try
+ {
+ indexBuilderService.Synchronize();
+ // Test initial synchronization.
+ var times = 0;
+ uint256 firstHash = await rpc.GetBlockHashAsync(0);
+ while (indexBuilderService.GetFilterLinesExcluding(firstHash, 101, out _).filters.Count() != 101)
+ {
+ if (times > 500) // 30 sec
+ {
+ throw new TimeoutException($"{nameof(IndexBuilderService)} test timed out.");
+ }
+ await Task.Delay(100);
+ times++;
+ }
+
+ using var client = new WasabiClient(new Uri(RegTestFixture.BackendEndPoint), null);
+ var response = await client.TorClient.SendAndRetryAsync(HttpMethod.Get, HttpStatusCode.OK, request);
+ using (HttpContent content = response.Content)
+ {
+ var resp = await content.ReadAsJsonAsync<StatusResponse>();
+ Assert.True(resp.FilterCreationActive);
+ }
+
+ // Simulate an unintended stop
+ await indexBuilderService.StopAsync();
+ indexBuilderService = null;
+
+ await rpc.GenerateAsync(1);
+
+ response = await client.TorClient.SendAndRetryAsync(HttpMethod.Get, HttpStatusCode.OK, request);
+ using (HttpContent content = response.Content)
+ {
+ var resp = await content.ReadAsJsonAsync<StatusResponse>();
+ Assert.True(resp.FilterCreationActive);
+ }
+
+ await rpc.GenerateAsync(1);
+
+ response = await client.TorClient.SendAndRetryAsync(HttpMethod.Get, HttpStatusCode.OK, request);
+ using (HttpContent content = response.Content)
+ {
+ var resp = await content.ReadAsJsonAsync<StatusResponse>();
+ Assert.False(resp.FilterCreationActive);
+ }
+ }
+ finally
+ {
+ if (indexBuilderService != null)
+ {
+ await indexBuilderService.StopAsync();
+ }
+ }
+ }
+
#endregion BackendTests
#region ServicesTests

ADD
WalletWasabi/Backend/Models/Responses/StatusResponse.cs
+namespace WalletWasabi.Backend.Models.Responses
+{
+ public class StatusResponse
+ {
+ public bool FilterCreationActive { get; set; }
+ }
+}

MODIFY
WalletWasabi/Blockchain/BlockFilters/IndexBuilderService.cs
WalletWasabi/Blockchain/BlockFilters/IndexBuilderService.cs
@@ -407,6 +407,14 @@ namespace WalletWasabi.Blockchain.BlockFilters
}
}
+ public FilterModel GetLastFilter()
+ {
+ using (IndexLock.Lock())
+ {
+ return Index.Last();
+ }
+ }
+
public async Task StopAsync()
{
if (BlockNotifier != null)

Add status request API