-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Change API to estimaterawfee #10543
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
Change API to estimaterawfee #10543
Conversation
utACK I prefer this API. I'll compile it and play with it a bit later today. Thanks for doing this 🥇 |
My reason for asking this is that it would allow someone to gather information using this RPC, without needing implementation-specific information. Sure, they'll need to understand the details to process the output anyway, but not the just collect. |
ACK. Seems to work well, and easier to log/use
|
Concept ACK |
concept ACK as well. |
Concept ACK; this will reduce the number of RPC calls we need to make to get a full picture of the fee market. |
rebased due to adjacent line change in src/rpc/client.cpp |
I've been running this patch for the last week on https://www.estimatefee.com to come up with estimates for how long a specific transaction will take to confirm. Haven't had any problems, and it works well and offers a nicer API. So ACK'ing again |
While we're changing the interface anyway, would it make sense to change the "information absent" response to something else than |
ACK |
utACK 7780de8 irrespective of if the "information absent" response is changed. |
OK Updated to change error reporting and information absent
When an answer can't be returned due to no fee rate meeting the threshold at the target (pass bucket is omitted but fail bucket still contains useful information):
When the target is not supported at a given horizon, the result is just omitted. Also if all feerates pass, the fail bucket is omitted:
When there is insufficient data to even calculate whether the target is met (pass bucket is omitted but fail bucket still contains useful information): *hacked to require many more data points for med and long horizons
|
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.
Partial review. Testing.
src/rpc/mining.cpp
Outdated
@@ -876,7 +876,7 @@ UniValue estimatesmartfee(const JSONRPCRequest& request) | |||
|
|||
UniValue estimaterawfee(const JSONRPCRequest& request) | |||
{ | |||
if (request.fHelp || request.params.size() < 1|| request.params.size() > 3) | |||
if (request.fHelp || request.params.size() < 1|| request.params.size() > 2) |
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.
Missing space before second ||
.
src/rpc/mining.cpp
Outdated
failbucket.push_back(Pair("totalconfirmed", round(buckets.fail.totalConfirmed * 100.0) / 100.0)); | ||
failbucket.push_back(Pair("inmempool", round(buckets.fail.inMempool * 100.0) / 100.0)); | ||
failbucket.push_back(Pair("leftmempool", round(buckets.fail.leftMempool * 100.0) / 100.0)); | ||
if (!(feeRate == CFeeRate(0))) { |
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.
Invert condition and switch blocks.
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.
I like having the success condition be the first thing you read, but I'll add a comment
src/rpc/mining.cpp
Outdated
for (FeeEstimateHorizon horizon : {FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}) { | ||
CFeeRate feeRate; | ||
EstimationResult buckets; | ||
if ((unsigned int)nBlocks <= ::feeEstimator.HighestTargetTracked(horizon)) { |
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 about early continue;
to avoid large indentation:
if ((unsigned int)nBlocks > ::feeEstimator.HighestTargetTracked(horizon)) continue;
13c683f
to
0220261
Compare
Addressed nits and squashed |
src/rpc/mining.cpp
Outdated
" \"totalconfirmed\" : x.x, (numeric) number of txs over history horizon in the feerate range that were confirmed at any point\n" | ||
" \"inmempool\" : x.x, (numeric) current number of txs in mempool in the feerate range unconfirmed for at least target blocks\n" | ||
" \"leftmempool\" : x.x, (numeric) number of txs over history horizon in the feerate range that left mempool unconfirmed after target\n" | ||
" }\n" |
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.
Nit, missing comma here and in the following lines.
src/rpc/mining.cpp
Outdated
@@ -876,7 +876,7 @@ UniValue estimatesmartfee(const JSONRPCRequest& request) | |||
|
|||
UniValue estimaterawfee(const JSONRPCRequest& request) | |||
{ | |||
if (request.fHelp || request.params.size() < 1|| request.params.size() > 3) | |||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) | |||
throw std::runtime_error( | |||
"estimaterawfee nblocks (threshold horizon)\n" |
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.
Nit, remove horizon
.
src/rpc/mining.cpp
Outdated
failbucket.push_back(Pair("inmempool", round(buckets.fail.inMempool * 100.0) / 100.0)); | ||
failbucket.push_back(Pair("leftmempool", round(buckets.fail.leftMempool * 100.0) / 100.0)); | ||
result.push_back(Pair("fail", failbucket)); | ||
const char* horizonNames[] = {"short", "medium", "long"}; |
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.
Nit, rename horizon_names
.
src/rpc/mining.cpp
Outdated
failbucket.push_back(Pair("leftmempool", round(buckets.fail.leftMempool * 100.0) / 100.0)); | ||
|
||
// CFeeRate(0) is used to indicate error as a return value from estimateRawFee | ||
if (!(feeRate == CFeeRate(0))) { |
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.
Maybe for another PR, but IMO operator!=
would be more expressive, no?
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.
Yeah I should have just added that operator before, since this has annoyed me a couple of times.
src/rpc/mining.cpp
Outdated
if ((unsigned int)nBlocks > ::feeEstimator.HighestTargetTracked(horizon)) continue; | ||
|
||
feeRate = ::feeEstimator.estimateRawFee(nBlocks, threshold, horizon, &buckets); | ||
UniValue horizonresult(UniValue::VOBJ); |
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.
Nit, snake case these multi word variables?
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.
i stuck with fixing the new ones
UniValue passbucket(UniValue::VOBJ); | ||
passbucket.push_back(Pair("startrange", round(buckets.pass.start))); | ||
passbucket.push_back(Pair("endrange", round(buckets.pass.end))); | ||
passbucket.push_back(Pair("withintarget", round(buckets.pass.withinTarget * 100.0) / 100.0)); |
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.
Should we make these round with 2 decimal places as strings? See https://stackoverflow.com/a/1343925.
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.
This RPC is kind of a low level debugging function anyway, so I might just save that for some later PR if people want it.
Addressed nits and squashed Thanks for review @promag ! |
@@ -40,6 +40,7 @@ class CFeeRate | |||
friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; } | |||
friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; } | |||
friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; } | |||
friend bool operator!=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK != b.nSatoshisPerK; } |
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.
Nit nit, place after operator==
.
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.
meh
@@ -190,6 +190,9 @@ class CBlockPolicyEstimator | |||
/** Empty mempool transactions on shutdown to record failure to confirm for txs still in mempool */ | |||
void FlushUnconfirmed(CTxMemPool& pool); | |||
|
|||
/** Calculation of highest target that estimates are tracked for */ | |||
unsigned int HighestTargetTracked(FeeEstimateHorizon horizon) const; |
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.
Since nBlocks
and also CBlockIndex::nHeight
are int
, why not return int
here too?
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.
Yeah I thought about that, but I figure it should really be an unsigned int, and so why not start moving things slowly in right direction.
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.
No problem, uint32_t
then?
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.
any reason?
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.
Best practice? Not network code but still. See https://stackoverflow.com/a/21621533.
feeRate = ::feeEstimator.estimateRawFee(nBlocks, threshold, horizon, &buckets); | ||
UniValue horizon_result(UniValue::VOBJ); | ||
UniValue errors(UniValue::VARR); | ||
UniValue passbucket(UniValue::VOBJ); |
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.
My suggestion was to snake case feeRate
, passbucket
and failbucket
.
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.
yeah i just fixed variables introduced in this PR, instead of changing preexisting variables
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.
Touched code should be fixed too?
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.
Maybe in this case it could have been since I touched a lot of the code, but I think in general it's easier not to make more changes than necessary in order to facilitate the review.
horizon_result.push_back(Pair("scale", (int)buckets.scale)); | ||
horizon_result.push_back(Pair("fail", failbucket)); | ||
errors.push_back("Insufficient data or no feerate found which meets threshold"); | ||
horizon_result.push_back(Pair("errors",errors)); |
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.
Nit, missing space before errors
.
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.
will fix if there are any more changes, but leave for now to avoid churn.
EstimationResult buckets; | ||
|
||
// Only output results for horizons which track the target | ||
if ((unsigned int)nBlocks > ::feeEstimator.HighestTargetTracked(horizon)) continue; |
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.
This omits the given horizon key from the output. Is this considered best practice for an API? An alternative is to return an array:
[{ "horizon": "short", "feerate": 0.00068495, ... }]
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 it's omitted because it is not meaningful to return an answer for a target higher than the horizon tracks.
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.
Hence the suggestion to return the array, a client iterates each element (if any) and uses the horizon
value.
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.
Oh sorry, I misunderstood at first. I suppose I'm not familiar enough with JSON practices to know what would be preferred.
tACK 6dc1410 |
re-utACK 6dc1410 |
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.
utACK 6dc1410. Left comments but please ignore any suggestions you think are not worth implementing here.
src/rpc/mining.cpp
Outdated
failbucket.push_back(Pair("leftmempool", round(buckets.fail.leftMempool * 100.0) / 100.0)); | ||
horizon_result.push_back(Pair("fail", failbucket)); | ||
} | ||
result.push_back(Pair(horizon_names[horizon], horizon_result)); |
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.
In commit "Change API to estimaterawfee"
This is pretty fragile. Consider replacing horizon_names
array with FeeEstimateHorizon -> std::string
function, or at adding a comment to FeeEstimateHorizon saying the enum values are used as array indices and need to be stable.
src/policy/fees.cpp
Outdated
return longStats->GetMaxConfirms(); | ||
} | ||
default: { | ||
return 0; |
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.
In commit "Add function to report highest estimate target tracked per horizon"
Seems like it would be safer to throw an error than to rely on code handling this to do something with this 0.
Report results for all 3 possible time horizons instead of specifying time horizon as an argument.
Addressed comments (rawpi.ver4) -> (rawapi.ver4.squash) -> 5e3b7b5 (rawapi.ver4.rebase) |
5e3b7b5 Improve error reporting for estimaterawfee (Alex Morcos) 1fafd70 Add function to report highest estimate target tracked per horizon (Alex Morcos) 9c85b91 Change API to estimaterawfee (Alex Morcos) Tree-SHA512: e624c6e7967e9e48abe49f5818bd674e5710e571cc093029d2f90d39fdfba3c1f30e83bf89f6dce97052b59a7d9636a64642ccfb26effd149c417d0afbed0c0b
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.
utACK 5e3b7b5. Same as previous review with the two suggested changes.
06bcdb8 Convert named argument from nblocks to conf_target (Alex Morcos) 439c4e8 Improve api to estimatesmartfee (Alex Morcos) Pull request description: Through 0.14 branch, the estimatesmartfee API was tagged "WARNING: This interface is unstable and may disappear or change!" and this warning is removed for 0.15, so any wanted API updates should happen now. The changes here are to make the additional parameter for conservative estimates a more general estimate_mode string , to omit the feerate and include an error string instead of returning -1 on error, and to do better parameter checking initially. ~It is only the last 2 commits, but it's built on #10706 and #10543~. See #10707 (comment) for renaming of nblocks argument to conf_target. Will need to be included before string freeze. PR description edited for clarity Tree-SHA512: 6d8ebee8bb410e2950ffd59663eebfed8d1611d995dc935bb91e430d9da7e2f306796f45631458376027d26341c660f09e825e61748103d2f2736ec6dc3df3ae
5e3b7b5 Improve error reporting for estimaterawfee (Alex Morcos) 1fafd70 Add function to report highest estimate target tracked per horizon (Alex Morcos) 9c85b91 Change API to estimaterawfee (Alex Morcos) Tree-SHA512: e624c6e7967e9e48abe49f5818bd674e5710e571cc093029d2f90d39fdfba3c1f30e83bf89f6dce97052b59a7d9636a64642ccfb26effd149c417d0afbed0c0b
5e3b7b5 Improve error reporting for estimaterawfee (Alex Morcos) 1fafd70 Add function to report highest estimate target tracked per horizon (Alex Morcos) 9c85b91 Change API to estimaterawfee (Alex Morcos) Tree-SHA512: e624c6e7967e9e48abe49f5818bd674e5710e571cc093029d2f90d39fdfba3c1f30e83bf89f6dce97052b59a7d9636a64642ccfb26effd149c417d0afbed0c0b
5e3b7b5 Improve error reporting for estimaterawfee (Alex Morcos) 1fafd70 Add function to report highest estimate target tracked per horizon (Alex Morcos) 9c85b91 Change API to estimaterawfee (Alex Morcos) Tree-SHA512: e624c6e7967e9e48abe49f5818bd674e5710e571cc093029d2f90d39fdfba3c1f30e83bf89f6dce97052b59a7d9636a64642ccfb26effd149c417d0afbed0c0b
5e3b7b5 Improve error reporting for estimaterawfee (Alex Morcos) 1fafd70 Add function to report highest estimate target tracked per horizon (Alex Morcos) 9c85b91 Change API to estimaterawfee (Alex Morcos) Tree-SHA512: e624c6e7967e9e48abe49f5818bd674e5710e571cc093029d2f90d39fdfba3c1f30e83bf89f6dce97052b59a7d9636a64642ccfb26effd149c417d0afbed0c0b
5e3b7b5 Improve error reporting for estimaterawfee (Alex Morcos) 1fafd70 Add function to report highest estimate target tracked per horizon (Alex Morcos) 9c85b91 Change API to estimaterawfee (Alex Morcos) Tree-SHA512: e624c6e7967e9e48abe49f5818bd674e5710e571cc093029d2f90d39fdfba3c1f30e83bf89f6dce97052b59a7d9636a64642ccfb26effd149c417d0afbed0c0b
5e3b7b5 Improve error reporting for estimaterawfee (Alex Morcos) 1fafd70 Add function to report highest estimate target tracked per horizon (Alex Morcos) 9c85b91 Change API to estimaterawfee (Alex Morcos) Tree-SHA512: e624c6e7967e9e48abe49f5818bd674e5710e571cc093029d2f90d39fdfba3c1f30e83bf89f6dce97052b59a7d9636a64642ccfb26effd149c417d0afbed0c0b
06bcdb8 Convert named argument from nblocks to conf_target (Alex Morcos) 439c4e8 Improve api to estimatesmartfee (Alex Morcos) Pull request description: Through 0.14 branch, the estimatesmartfee API was tagged "WARNING: This interface is unstable and may disappear or change!" and this warning is removed for 0.15, so any wanted API updates should happen now. The changes here are to make the additional parameter for conservative estimates a more general estimate_mode string , to omit the feerate and include an error string instead of returning -1 on error, and to do better parameter checking initially. ~It is only the last 2 commits, but it's built on bitcoin#10706 and bitcoin#10543~. See bitcoin#10707 (comment) for renaming of nblocks argument to conf_target. Will need to be included before string freeze. PR description edited for clarity Tree-SHA512: 6d8ebee8bb410e2950ffd59663eebfed8d1611d995dc935bb91e430d9da7e2f306796f45631458376027d26341c660f09e825e61748103d2f2736ec6dc3df3ae
06bcdb8 Convert named argument from nblocks to conf_target (Alex Morcos) 439c4e8 Improve api to estimatesmartfee (Alex Morcos) Pull request description: Through 0.14 branch, the estimatesmartfee API was tagged "WARNING: This interface is unstable and may disappear or change!" and this warning is removed for 0.15, so any wanted API updates should happen now. The changes here are to make the additional parameter for conservative estimates a more general estimate_mode string , to omit the feerate and include an error string instead of returning -1 on error, and to do better parameter checking initially. ~It is only the last 2 commits, but it's built on bitcoin#10706 and bitcoin#10543~. See bitcoin#10707 (comment) for renaming of nblocks argument to conf_target. Will need to be included before string freeze. PR description edited for clarity Tree-SHA512: 6d8ebee8bb410e2950ffd59663eebfed8d1611d995dc935bb91e430d9da7e2f306796f45631458376027d26341c660f09e825e61748103d2f2736ec6dc3df3ae
5e3b7b5 Improve error reporting for estimaterawfee (Alex Morcos) 1fafd70 Add function to report highest estimate target tracked per horizon (Alex Morcos) 9c85b91 Change API to estimaterawfee (Alex Morcos) Tree-SHA512: e624c6e7967e9e48abe49f5818bd674e5710e571cc093029d2f90d39fdfba3c1f30e83bf89f6dce97052b59a7d9636a64642ccfb26effd149c417d0afbed0c0b
06bcdb8 Convert named argument from nblocks to conf_target (Alex Morcos) 439c4e8 Improve api to estimatesmartfee (Alex Morcos) Pull request description: Through 0.14 branch, the estimatesmartfee API was tagged "WARNING: This interface is unstable and may disappear or change!" and this warning is removed for 0.15, so any wanted API updates should happen now. The changes here are to make the additional parameter for conservative estimates a more general estimate_mode string , to omit the feerate and include an error string instead of returning -1 on error, and to do better parameter checking initially. ~It is only the last 2 commits, but it's built on bitcoin#10706 and bitcoin#10543~. See bitcoin#10707 (comment) for renaming of nblocks argument to conf_target. Will need to be included before string freeze. PR description edited for clarity Tree-SHA512: 6d8ebee8bb410e2950ffd59663eebfed8d1611d995dc935bb91e430d9da7e2f306796f45631458376027d26341c660f09e825e61748103d2f2736ec6dc3df3ae
Report results for all 3 possible time horizons instead of specifying time horizon as an argument.
@sipa requested this. I'm indifferent, but we should merge this for 0.15 if it's considered a better way to present the information, before the old api is released.
@instagibbs @RHavar both found the old interface a bit unintuitive
@jlopp any thoughts?