-
Notifications
You must be signed in to change notification settings - Fork 37.1k
Improve usage of fee estimation code #6134
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
Conversation
Seems quite reasonable - ut ACK |
Concept ACK |
7ad61bc
to
4f872ce
Compare
OK I reworked this to be a bit better, and combined it with the patch that increases the success threshold to 95%. @jonasschnelli I did something much simpler in the interface. The slider just indicates the # of blocks for which your fee estimate was valid. Perhaps we need to consider some kind of additional UI element that would explain to people why they aren't able to get an estimate for a smaller # of blocks. I think it'll be very rare and maybe never that you'll successfully get an estimate for 1 block, which people will probably try to do. |
4f872ce
to
b79c9f2
Compare
The last commit is as of yet untested, but should resolve some of the issues around accidentally generating transactions that wouldn't be accepted to your own mempool |
Needs rebase (trivial QT: Probably not related to this PR, but is there a reason why the slider – by default – is on the left side "slow confirmation time" and not at the very right side? I guess less then <1% of transactions aim for confirmation >=25blocks. QT: In my case (mainnet at current height), num-blocks 25 till 18 had the same fee. This feels bad for users, because they might think, "why should I pay a higher fee than i really need for my target?". We need to aggregate num-blocks with the same fee (stop at block 18, don't go further down with the fee, up with the num block target). Also num-blocks 10 and 11 had the same fee, these should be aggregated. There should be something when calling |
@jonasschnelli This PR should prevent getting a -1 unless you directly call the RPC call estimatefee. I might still expose estimateapproxfee, but for anyone using GUI or wallet code that automatically generates fee, they should now get the best answer possible. I figured that for outside users, they could emulate the logic of estimateapproxfee themselves for now. In the future I agree there should be an RPC call which just does the right thing, but I wasn't ready to expose that now as I'm not sure exactly what it should look like yet. |
b79c9f2
to
c9404f5
Compare
Rebased |
Concept(s) ACK. |
added some checks in the unit test and exposed the functions via RPC (with a warning) and tested in the RPC test. |
Concept ACK. Plans to test this soon. |
These are more useful fee and priority estimation functions. If there is no fee/pri high enough for the target you are aiming for, it will give you the estimate for the lowest target that you can reliably obtain. This is better than defaulting to the minimum. It will also pass back the target for which it returned an answer.
This provides more conservative estimates and reacts more quickly to a backlog. Unfortunately the unit test for fee estimation depends on the success threshold (and the decay) chosen; also modify the unit test for the new default success thresholds.
Also add testing for estimatesmartfee in smartfees.py
f2e9aab
to
56106a3
Compare
Rebased with a name change to estimateSmartFee instead of Approx |
ACK apart from those nits |
*answerFoundAtTarget = confTarget - 1; | ||
|
||
// If mempool is limiting txs , return at least the min fee from the mempool | ||
CAmount minPoolFee = pool->GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE)
be an attribute so that it can be calculated just once in the constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. But honestly it seems a bit silly to me that this is not an attribute of the mempool. I understand the point of keeping policy out of the mempool, but why should you need to be aware of the max size of the mempool just to ask what it's min fee is. The one advantage I can see for the current structure is that you can call TrimToSize with some other number to do testing.
Perhaps TrimToSize should take a sizelimit, and set an internal attribute of the mempool that GetMinFee uses?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are right: it should probably be an attribute of CTxMemPool instead, and minPoolFee could be passed here instead of the CTxMemPool pointer. In fact, CTxMemPool depend on CBlockPolicyEstimator, so CBlockPolicyEstimator shouldn't depend on CTxMemPool too (sigh, I had a branch in which neither one depended on the other at least once but now just https://github.com/jtimon/bitcoin/commits/policy-minrelayfee-0.12.99 ...).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't pass the minFee it's dynamic, you have to ask the mempool for it.
I think the CBlockPolicyEstimator should come out of the mempool though for sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I'm saying is you can ask the mempool before calling this (ie rplace the pool pointer parameter with const CAmount& minPoolFee in this new method).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please look at https://github.com/jtimon/bitcoin/tree/6134-nits
By the way, we should solve the circular dependency by separating CTxMemPoolEntry. That way txmempool.cpp includes policy/fees.h, and policy/fees.cpp includes txmempoolentry.h (but not txmempool.h). Just came to mind again, not saying is within the scope of this PR.
Concept ACK with a very fast review. Again, this would be simpler if there was no priority... |
@@ -504,6 +505,33 @@ CFeeRate CBlockPolicyEstimator::estimateFee(int confTarget) | |||
return CFeeRate(median); | |||
} | |||
|
|||
CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoundAtTarget, const CTxMemPool *pool) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed nits. |
My main nit hasn't been addressed, which is not creating a new circular dependency (currently CTxMemPool depends on CBlockPolicyEstimator, but CBlockPolicyEstimator doesn't depend on CTxMemPool until this PR) that is unnecessary (as shown in jtimon@6963b9c ). |
e304432 Pass reference to estimateSmartFee and cleanup whitespace (Suhas Daftuar) 56106a3 Expose RPC calls for estimatesmart functions (Alex Morcos) e93a236 add estimateSmartFee to the unit test (Alex Morcos) 6303051 EstimateSmart functions consider mempool min fee (Alex Morcos) f22ac4a Increase success threshold for fee estimation to 95% (Alex Morcos) 4fe2823 Change wallet and GUI code to use new smart fee estimation calls. (Alex Morcos) 22eca7d Add smart fee estimation functions (Alex Morcos)
I guess I'll create a new PR removing the new and unnecessary circular dependency introduced... |
Opened #7115 to fix the new circular dependency introduced despite my insistence and despite coding the commit to be squashed here to avoid that circular dependency... |
For future reference NACK this PR. I'm really disappointed about @morcos being so stubborn and insisting on introducing the unnecessary circular dependency and that he can even accept the most minimal way to remove it (see the first commit in #7115 ), but I like circular discussions even less than I like circular dependencies and nobody else seems to care enough. So let's leave the circular dependency, but then I need to at least do what I should have done from the beginning and will do next time: nack instead of coding nits to be ignored. NACK nack nacking... |
The practical problem is that we can't hold up required changes forever because they have some coding nits. There's, unfortunately, a compromise between accumulating some technical debt or having any single change take forever because of architectural concerns. |
This was merged without my nit and morcos insists on nacking any code that removes the circular dependency he unnecessarily introduced. I think it has little to do with "prs taking forever". But hey I'm in favor of merging bip68 and other PRs that are taking forever if you want to change the subject. |
He does not nack removing the circular dependency. He disagrees with making
the estimation code users responsible for knowing there is a limit.
|
See yesterday's IRC discussion, yes, he even nacks the most minimal way to remove the circular dependency (the first commit currently in #7115 ) and he will not provide an alternative because he does not want to remove the dependency. |
4038de4 [QA] Restore 'feature_fee_estimation.py' functional test (random-zebra) 988f349 [qt] Properly display required fee instead of minTxFee (random-zebra) c5c9df0 [Trivial] Fix typos (random-zebra) a8fa99b [Trivial] Remove redundat check in ContainsZerocoins (random-zebra) 8ebcbcd PolicyEstimator: exclude zerocoin spends when computing estimates (random-zebra) b67049b Create new BlockPolicyEstimator for fee estimates (random-zebra) Pull request description: This introduces the new fee and priority estimation code described here <https://www.mail-archive.com/bitcoin-development@lists.sourceforge.net/msg06405.html>. Instead of calculating the median fee for each possible number of blocks needed to confirm, the new code divides the possible fee rates into buckets (spaced logarithmically) and keeps track of the number of blocks needed to confirm for each transaction in each bucket. Backports: - bitcoin#5159 - bitcoin#6887 except for the functional test (`smartfees.py`) which is based on an older version of the framework. Instead I've restored a more recent `feature_fee_estimation.py` (commenting out the check for `estimatesmartfee` which can be reintroduced once bitcoin#6134 is backported). Additional commits exclude zerocoins txes from the estimates calculation, as they have fixed fee/priority. ACKs for top commit: Fuzzbawls: ACK 4038de4 furszy: ACK 4038de4 and merging Tree-SHA512: 25777af469f7fa84d2dab991544392bea8418bccb4d2c23113de2c6ed7047891bdaedad1728cb04ba343e82f4bc0c1446f88e28def698dd25168769abf8620bb
3aded91 [Trivial] Temporarily comment-out priority check in policyestimator test (random-zebra) 245c3df [Tests] Enable smartfee test in feature_fee_estimation.py (random-zebra) a06e9ff Pass reference to estimateSmartFee and cleanup whitespace (Suhas Daftuar) 9df303d Expose RPC calls for estimatesmart functions (furszy) 826aaaa add estimateSmartFee to the unit test (Alex Morcos) e34b723 EstimateSmart functions consider mempool min fee (Alex Morcos) 649b4fc Increase success threshold for fee estimation to 95% (Alex Morcos) 4893a7c Change wallet and GUI code to use new smart fee estimation calls. (furszy) e8fc55a Add smart fee estimation functions (Alex Morcos) Pull request description: Another back port, coming from dashpay#6134 . > When automatically adding a fee estimate to a transaction and in the event no estimate is available for the desired confirmation target, it makes more sense to default to a fee estimate for a worse confirmation target rather than the hard coded minimum. > TODO: Left to back port smartfees.py. We need it to be able to move forward in #1726 ACKs for top commit: Fuzzbawls: utACK 3aded91 random-zebra: ACK 3aded91 and merging... Tree-SHA512: 6f52d29267da0b20e54ed680743b341c1e616986dabf72916499cf5936d73d552bab907038e83b65625d6bf9dbd0adbb1e1300a15622d94908f54e6fe270f2f6
When automatically adding a fee estimate to a transaction and in the event no estimate is available for the desired confirmation target, it makes more sense to default to a fee estimate for a worse confirmation target rather than the hard coded minimum.
I'm open to a different way of exposing this functionality if there is a better suggestion.
@cozz I don't know anything about QT code, so I think what I did in sendcoinsdialog.cpp is pretty hacky, although it appears to have the desired effect. Perhaps you could take a look and suggest a better approach? This is my attempt to address the concern I mentioned in this comment: #5200 (comment)