From 24d24f2f252df4d1bd66cc530d29c2478aaa38c5 Mon Sep 17 00:00:00 2001 From: Nicolas Dorier Date: Fri, 29 Nov 2024 10:01:21 +0900 Subject: [PATCH] Fix timeout errors, Fix NBXplorer hanging when exiting (#491) --- NBXplorer/Backend/DbConnectionHelper.cs | 12 ++++++++++-- NBXplorer/Backend/Indexer.cs | 4 ++-- NBXplorer/Backend/Repository.cs | 13 ++++++------- .../RefreshWalletHistoryPeriodicTask.cs | 6 +++++- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/NBXplorer/Backend/DbConnectionHelper.cs b/NBXplorer/Backend/DbConnectionHelper.cs index cc475a5fc..a46b032d6 100644 --- a/NBXplorer/Backend/DbConnectionHelper.cs +++ b/NBXplorer/Backend/DbConnectionHelper.cs @@ -8,6 +8,7 @@ using System.Data; using System.Data.Common; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace NBXplorer.Backend @@ -58,7 +59,7 @@ public static void Register(NpgsqlDataSourceBuilder dsBuilder) dsBuilder.MapComposite("outpoint"); dsBuilder.MapComposite("nbxv1_ds"); } - public async Task FetchMatches(MatchQuery matchQuery) + public async Task FetchMatches(MatchQuery matchQuery, CancellationToken cancellationToken) { var outs = new List(matchQuery.Outs.Count); var ins = new List(matchQuery.Ins.Count); @@ -93,7 +94,14 @@ public async Task FetchMatches(MatchQuery matchQuery) parameters.Add("in_outs", outs); parameters.Add("in_ins", ins); parameters.Add("has_match", dbType: System.Data.DbType.Boolean, direction: ParameterDirection.InputOutput); - await Connection.QueryAsync("fetch_matches", parameters, commandType: CommandType.StoredProcedure); + var command = new CommandDefinition( + commandText: "fetch_matches", + parameters: parameters, + commandType: CommandType.StoredProcedure, + commandTimeout: ((NpgsqlConnection)Connection).CommandTimeout * 3, + cancellationToken: cancellationToken + ); + await Connection.QueryAsync(command); return parameters.Get("has_match"); } diff --git a/NBXplorer/Backend/Indexer.cs b/NBXplorer/Backend/Indexer.cs index d1920843e..befc97dbd 100644 --- a/NBXplorer/Backend/Indexer.cs +++ b/NBXplorer/Backend/Indexer.cs @@ -420,7 +420,7 @@ private async Task UpdateState(Node node) private async Task GetDefaultCurrentLocation(CancellationToken token) { if (ChainConfiguration.StartHeight > BlockchainInfo.Headers) - throw new InvalidOperationException($"{Network.CryptoCode}: StartHeight should not be above the current tip"); + throw new InvalidOperationException($"{Network.CryptoCode}: StartHeight ({ChainConfiguration.StartHeight}) should not be above the current tip ({BlockchainInfo.Headers})"); BlockLocator blockLocator = null; if (ChainConfiguration.StartHeight == -1) { @@ -464,7 +464,7 @@ private async Task SaveMatches(DbConnectionHelper conn, List transa { await conn.NewBlock(slimChainedBlock); } - var matches = await Repository.GetMatches(conn, transactions, slimChainedBlock, now, blockMatch: true, useCache: true); + var matches = await Repository.GetMatches(conn, transactions, slimChainedBlock, now, useCache: true, cancellationToken: cts.Token); _ = AddressPoolService.GenerateAddresses(Network, matches); long confirmations = 0; diff --git a/NBXplorer/Backend/Repository.cs b/NBXplorer/Backend/Repository.cs index f5ddd485a..5f812c211 100644 --- a/NBXplorer/Backend/Repository.cs +++ b/NBXplorer/Backend/Repository.cs @@ -13,7 +13,6 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NBitcoin.Altcoins.Elements; -using NBXplorer.Altcoins.Liquid; using NBXplorer.Client; using NBitcoin.Scripting; using System.Text.RegularExpressions; @@ -522,7 +521,7 @@ public async Task Unblind(RPCClient rpc, DerivationStrategyBase ts, ElementsTran } record UpdateMatchesOuts(string tx_id, long idx, string asset_id, long value); - public async Task GetMatches(DbConnectionHelper connection, IList txs, SlimChainedBlock slimBlock, DateTimeOffset now, bool blockMatch, bool useCache) + public async Task GetMatches(DbConnectionHelper connection, IList txs, SlimChainedBlock slimBlock, DateTimeOffset now, bool useCache, CancellationToken cancellationToken = default) { List records = new(txs.Count); foreach (var tx in txs) @@ -532,7 +531,7 @@ public async Task GetMatches(DbConnectionHelper connection int i = 0; foreach (var tx in txs) { - var record = SaveTransactionRecord.Create(tx, slimBlock: slimBlock, blockIndex: blockMatch ? i : null, seenAt: now); + var record = SaveTransactionRecord.Create(tx, slimBlock: slimBlock, blockIndex: i, seenAt: now); if (!useCache || !noMatchCache.Contains(record.Id)) records.Add(record); i++; @@ -546,9 +545,9 @@ public async Task GetMatches(DbConnectionHelper connection records.Add(record); } } - var query = MatchQuery.FromTransactions(records.Select(r => r.Transaction), MinUtxoValue); - var matches = await SaveMatches(connection, query, records); + var query = MatchQuery.FromTransactions(records.Select(r => r.Transaction), MinUtxoValue); + var matches = await SaveMatches(connection, query, records, cancellationToken); // Let's remember unconfirmed that didn't match so the processing of a block is faster if (useCache && slimBlock is null) @@ -561,7 +560,7 @@ public async Task GetMatches(DbConnectionHelper connection } return matches.TrackedTransactions; } - async Task<(TrackedTransaction[] TrackedTransactions, SaveTransactionRecord[] Saved)> SaveMatches(DbConnectionHelper connection, MatchQuery matchQuery, IList records) + async Task<(TrackedTransaction[] TrackedTransactions, SaveTransactionRecord[] Saved)> SaveMatches(DbConnectionHelper connection, MatchQuery matchQuery, IList records, CancellationToken cancellationToken = default) { HashSet unconfTxs = await connection.GetUnconfirmedTxs(); Dictionary txs = new(); @@ -581,7 +580,7 @@ public async Task GetMatches(DbConnectionHelper connection var elementContext = Network.IsElement ? new ElementMatchContext() : null; - if (!await connection.FetchMatches(matchQuery)) + if (!await connection.FetchMatches(matchQuery, cancellationToken)) goto end; using (var result = await connection.Connection.QueryMultipleAsync( "SELECT * FROM matched_outs;" + diff --git a/NBXplorer/HostedServices/RefreshWalletHistoryPeriodicTask.cs b/NBXplorer/HostedServices/RefreshWalletHistoryPeriodicTask.cs index 7f94ad7aa..766080780 100644 --- a/NBXplorer/HostedServices/RefreshWalletHistoryPeriodicTask.cs +++ b/NBXplorer/HostedServices/RefreshWalletHistoryPeriodicTask.cs @@ -27,7 +27,11 @@ public RefreshWalletHistoryPeriodicTask(DbConnectionFactory connectionFactory) public async Task Do(CancellationToken cancellationToken) { await using var conn = await _DS.ReliableOpenConnectionAsync(); - await conn.ExecuteAsync("SELECT wallets_history_refresh();"); + var command = new CommandDefinition( + commandText: "SELECT wallets_history_refresh();", + commandType: System.Data.CommandType.Text, + cancellationToken: cancellationToken); + await conn.ExecuteAsync(command); } public ValueTask DisposeAsync()