Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrading ThirdPartyFeeProvider to support list of fee providers #13016

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

csiki2
Copy link
Collaborator

@csiki2 csiki2 commented May 10, 2024

Upgrading ThirdPartyFeeProvider to support list of fee providers.

Later HybridFeeProvider can be removed since it's a sort of duplicate.

@csiki2 csiki2 requested review from molnard, Szpoti and Whem May 10, 2024 13:04
@lontivero
Copy link
Collaborator

lontivero commented May 11, 2024

We are planning to move the responsibility of fetching the mining fee rates from the server to the client. The ultimate goal is to make Wasabi to work without a central server, or at least that's the direction I think we have to go. Each user should be able to chose which fee provider to trust on, mempool.space is pretty popular and I am sure it would be among the most chosen ones.

We cannot maintain tens of fee providers and, even when they would all look exactly the same, because after all they all have to make a http request to get a json containing a list of (target, fee rate) pairs, we should support many of these fee rate providers.

So, the idea is to simplify that task. Imagine something like a WebFeeRateProvider, a PeriodicRunner as it is the one that created in this PR, that can be used with any fee rate source. Something like this:

class WebFeeProvider : PeriodicRunner
{
        private IFeeProviderHandler _feeProviderHandler;
        public FeeRateCollection FeeRates { get; private set; }

        public async Task ActionAsync()
	{
             var json = _httpClient.SendAsync(HttpMethod.Get, _feeProviderHandler.ApiUrl)
             FeeRates = _feeProviderHandler.Parse(json);
        }
}


interface IFeeProviderHandler {
   string ApiUrl { get; }
   FeeRateCollection Parse(JObject /*or string*/ apiResponse);
}

Then, if you implement this, your MempoolSpaceFeeRateProvider can be implemented with a MempoolFeeRateProviderHandler that maps, using your BlockMap, the mempool.space response to the FeeRateCollection (AllFeeEstimates is in the code btw, sorry for the confusion)

@csiki2
Copy link
Collaborator Author

csiki2 commented May 12, 2024

This is on the client side.
The whole point of the ThirdPartyFeeProvider change that the WasabiSyncronizer is just one of the list and later we can remove it anytime from the list.
We already have an interface for the fee provider, I don't understand why we intend to make it more complex than needed, is there any immediate benefit?
Ofc, if we begin to use many-many similar approach it might worth to make an ancestor (or even better solution).
To be fair I plan to remove the HybridFeeProvider later as well as it's a duplicate.
I recommend to accept and merge this in, and then we can discuss what else should be done at this area of code.

@csiki2 csiki2 requested review from molnard and removed request for molnard May 12, 2024 13:52
@csiki2
Copy link
Collaborator Author

csiki2 commented May 12, 2024

Created #13022 as a feature request.

@csiki2 csiki2 requested a review from kristapsk May 12, 2024 14:13
@kiminuo kiminuo changed the title Supporting mempool.space fee estimation Support for mempool.space fee estimator May 12, 2024
@kiminuo kiminuo changed the title Support for mempool.space fee estimator Support for mempool.space fee rate estimator May 12, 2024
@csiki2 csiki2 changed the title Support for mempool.space fee rate estimator Upgrading ThirdPartyFeeProvider too support list of fee providers May 13, 2024
Upgrading ThirdPartyFeeProvider too support list of fee providers.

Co-Authored-By: Kimi <58662979+kiminuo@users.noreply.github.com>
Copy link
Collaborator

@turbolay turbolay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, it's nice that you split this PR with the integration of mempool.space, that we can easily do later.

The code is a bit hard to understand but the concept is OK. Code mostly LGTM. I just have 2 small questions that I wrote as comments.

You mentioned in the meeting that the codebase in general lacks useful comments, maybe adding some to this kind of PR is a good way to not worsen the problem. FYI most uncommented features were coded early, and most new features are properly commented.

I made turbolay@6c4a066. You can choose whether to apply it or not, it applies some suggestions from Rider and fixes few warnings.

As @kiminuo mentioned, it would be great to have Unit Tests as the concept is not trivial (eg a test that shows that priority is respected, another one to ensure that priority goes back to first provider when it's not OnError anymore and that other providers are paused)

@csiki2 csiki2 requested review from turbolay and kiminuo May 14, 2024 07:35
@csiki2
Copy link
Collaborator Author

csiki2 commented May 14, 2024

First, it's nice that you split this PR with the integration of mempool.space, that we can easily do later.

You mentioned in the meeting that the codebase in general lacks useful comments, maybe adding some to this kind of PR is a good way to not worsen the problem. FYI most uncommented features were coded early, and most new features are properly commented.

You have a point there. I will create a commit that has the comments you already asked.

I made turbolay@6c4a066. You can choose whether to apply it or not, it applies some suggestions from Rider and fixes few warnings.

I have mixed feelings here.
In general I like the early returns, but the extra brackets greatly reduces it's usefulness and in some cases even worsen the readability.
For example, the
'''
if (inError && !InError && LastStatusChange - DateTimeOffset.UtcNow > TimeSpan.FromMinutes(1))
'''
is easier to read (at least to me) then it's negated logic.
I added some of your recommendations.

As @kiminuo mentioned, it would be great to have Unit Tests as the concept is not trivial (eg a test that shows that priority is respected, another one to ensure that priority goes back to first provider when it's not OnError anymore and that other providers are paused)

Began to write a unit test (and caught a bug, khm).

Copy link
Collaborator

@turbolay turbolay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed 2 commits on this PR, harmless simply style and a small addition to the test

However, upon testing there are 2 things not really great with the implementation:

  • It's too long to wait for the backup when a provider is OnError
  • Excluding for the WasabiSynchronizer (which long term won't be a fee provider), it's useless to wait 1 minute when being OnError, because the period of the other provider (currently only Blockstream) is higher than 1 minute

I can suggest 2 things:

  • Reduce the period of the providers, but return immediately if last result was less than 3 minutes ago turbolay@257d242 -> This change might be enough by itself.
  • Expose TriggerRound in IThirdPartyFeeProvider and call it when IsPaused goes from false to true in SetPauseStates turbolay@bea838a

As mentioned, 2nd suggestion might be overkill, as first one would already improve (and we would need to wait max 10s). So you can choose whether to implement or not, modify my suggestions etc... Your call.

With one modification of the kind, this PR can be merged.

@csiki2
Copy link
Collaborator Author

csiki2 commented May 15, 2024

I would go with the second as its cleaner.
Let me check whether it is an issue that we willingly add the same method name for the 2 interfaces.

@csiki2
Copy link
Collaborator Author

csiki2 commented May 15, 2024

I went with the second approach, but with separate method name for cleaner interface (TriggerOutOfOrderUpdate) + unit test.
If you have other method name suggestion, please let me know.

Copy link
Collaborator

@molnard molnard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We talked with Csiki on Slack. The idea here is to make ThirdPartyFeeProvider the one and only API for providing fees. There are multiple approaches IMO this is reasonable first step, because it is not breaking anything and using the current structure but opens the space for increments.

@turbolay
Copy link
Collaborator

Why did you override my commits?

@csiki2
Copy link
Collaborator Author

csiki2 commented May 16, 2024

You told me, I can choose.
I chose the second one, but needed to change (and fix) it, so ended up removing them.
Sorry for the inconvenience.

@turbolay
Copy link
Collaborator

turbolay commented May 16, 2024

No, I pushed commits on your PR to fix style that you overrode with a forced push, mentioned here:

I pushed 2 commits on this PR, harmless simply style and a small addition to the test

Anyway, lost too much time on this, won't happen again.

@yahiheb
Copy link
Collaborator

yahiheb commented May 16, 2024

Isn't this PR now obsolete with #13035?

@csiki2
Copy link
Collaborator Author

csiki2 commented May 16, 2024

"No, I pushed commits on your PR to fix style that you overrode with a forced push, mentioned here:"
I remember only these two commits with your suggestions. Way earlier was a squash.

@csiki2
Copy link
Collaborator Author

csiki2 commented May 16, 2024

Isn't this PR now obsolete with #13035?

Different branch.

@csiki2
Copy link
Collaborator Author

csiki2 commented May 16, 2024

No, I pushed commits on your PR to fix style that you overrode with a forced push, mentioned here:

I pushed 2 commits on this PR, harmless simply style and a small addition to the test

Anyway, lost too much time on this, won't happen again.

Argh. My fault. Terribly sorry about that. :(

@csiki2 csiki2 requested review from molnard and removed request for kristapsk and kiminuo May 16, 2024 15:17
@yahiheb
Copy link
Collaborator

yahiheb commented May 16, 2024

Isn't this PR now obsolete with #13035?

Different branch.

That branch is the future of Wasabi Wallet that's why others are working on it.
AFAIK soon it will be merged to master and all of this will be overridden.

molnard
molnard previously approved these changes May 17, 2024
Copy link
Collaborator

@molnard molnard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what is the future of this, meanwhile the other PR was borned - anyway I tested it and reviewed the code.

tACK

@turbolay
Copy link
Collaborator

See why I said I would merge #13031 after

CleanShot 2024-05-17 at 06 48 11@2x

@csiki2
Copy link
Collaborator Author

csiki2 commented May 17, 2024

I don't have high hopes that this change will be merged. Still, I fixed the conflict.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants