dgarage / NBXplorer

NBitcoin Explorer
MIT License
320 stars 210 forks source link

BTC: Call to NBXplorer GetUTXOsAsync timed out, this should never happen, plasse report this issue to NBXplorer developerss #120

Open ghost opened 5 years ago

ghost commented 5 years ago

Hello ,

I deployed a btcpayserver to receive bitcoin payments.

The btcpayserver log has appeared "BTC: Call to NBXplorer GetUTXOsAsync timed out, this should never happen, plasse report this issue to NBXplorer developerss" (btcpayserver )and the user transaction will be delayed for a long time before being confirmed by btcpayserver.

_ukb0_6lz48t 3far e0p

I tried to debug NBXplorer and found that the GetUTXOs function took a very high time.

As a temporary solution, I modified the NBXplorer httpclient timeout to 10 minutes. After modifying the dependent library and recompiling btcpayserver, the frequency of the problem seems to be reduced, but there will still be errors. In addition, a warning message sometimes appears, showing that GetUTXOsAsync takes 100+ seconds to execute.

NBXplorer\NBXplorer.Client\ExplorerClient.cs
        Private static readonly HttpClient SharedClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(10 * 60) };

Sorry, I am not familiar with Bitcoin. C# has not been in contact for several years. I can't solve this problem. Can only come to ask what is the reason for this question? what should I do? thank you very much

NicolasDorier commented 5 years ago

Is there a lot of transaction to your derivation scheme? A workaround is to create a new derivation scheme and send the money there and using that instead.

I have a longer time workaround I can work on. But just want to be sure you reached the limit.

ghost commented 5 years ago

The order timeout is 48 hours. There are probably less than 300 orders per day, of which more than 100 have been paid. Bitpay has been in use for a few months.

What does the solution mean to create a new payment address?

Thanks

NicolasDorier commented 5 years ago

Yes, use a new derivation scheme. You will not experience timeout. That said this is something I need to solve.

ghost commented 5 years ago

thank you very much.

This timeout problem is that GetUTXO will query all transactions at the specified address. Due to too many transactions at the current address, the query is time consuming. After updating the address, there will be no query timeout due to the small number of new address transactions. Is the description above correct?

Currently using the electrum wallet, the actual btcpay process does not rely on the electrum wallet, so replacing the electrum wallet for other wallet software does not help solve the problem?

NicolasDorier commented 5 years ago

Your description is correct. I was not expecting this problem to happen soon. How many transactions your wallet has?

Yes Electrum wallet does not depends on BTCPay at all, so this won't solve the issue.

I worked this weekend on trying to solve this issue by adding a feature which would prune transactions which do not affect the UTXO. Are you open to give a try?

Those transaction will still appear in the transaction list (GetTransactions) but their "balance change" will be 0.

It is ready to commit, and it is experimental so I would advise you to take a backup before using it. Are you willing to try?

NicolasDorier commented 5 years ago

Ok so I pushed.

This is experimental, so make a backup in case.

Run with --autopruning=30. What this does is that it measures the time it takes to build the UTXO set when you call GetUTXOs. If it takes more than 30 seconds, then it will attempt to prune 1/4 of your oldest transaction who do not have any impact on the UTXO.

Everytimes you call GetUTXOs, it will do it. So in your case it might prune several time.

The pruned transactions will still appear in GetTransactions though without the transaction information, with a ChangeBalance of 0 and without any input or output.

If you change 30 to say 10, it will target a response time of 10 sec max.

NicolasDorier commented 5 years ago

Note that I might still break it so I am just asking you to try and let me know if your UTXO is still the same after doing it, and faster. DO NOT migrate now.

NicolasDorier commented 5 years ago

There is a second options I am envisionning: Since Bitcoin Core 0.17.0, there is scanutxoset which allow me to fetch all the UTXO in a wallet. So what I can do is to prune all the history of a wallet, then call scanutxoset, to retrieve only the current UTXOs.

ghost commented 5 years ago

I am very sorry, I am busy recently.

A transaction that was paid around 150 per day, which lasted for 6 months, was roughly 150306=27000 transactions.

Is there any danger in this experimental function? Is it possible to cause financial errors? Because it is an online production environment, I don't dare to use new experimental features.

Another thought is that if the operating system increases the load for a short time due to other reasons, will it make NBX incorrectly cut the normal transaction?

NicolasDorier commented 5 years ago

Ok so wait a bit. Thanks for your input. Let me do more test. As workaround use new wallet for now.

NicolasDorier commented 5 years ago

NBXplorer can't miss transactions, even if the OS increase load

sigHash commented 5 years ago

Not sure what's the best way to implement it, but being able to conduct fast searches against all utxos of a derivation schemes is highly valuable. For example, I have different algorithms for utxo selection that amount to a specific target but they all have to wait for GetUTXOsAsync.

NicolasDorier commented 5 years ago

@sigHash I implemented --autopruning=30 which will prune your transaction history if the requests to get UTXO takes more than 30 seconds. You may want to try this.

NicolasDorier commented 5 years ago

A pruned transaction will still appear in GetTransactions but with the balanceChange to 0 and Transaction property to null. But because it has no impact on UTXO, it should make GetUTXO fast.

sigHash commented 5 years ago

Thanks for the new feature. After multiple pruning, is it possible to get to sub 100ms? Would be nice if we could plot the response time vs. numUTXOS.

NicolasDorier commented 5 years ago

@sigHash it depends on the number of UTXOs

NicolasDorier commented 5 years ago

I managed to remove most of the calls that could take time (like hashing, or derivation) so really now the bottleneck is getting the transactions out of the database.

sigHash commented 5 years ago

Awesome! Thanks!