-
Notifications
You must be signed in to change notification settings - Fork 37.7k
RPC: Introduce getblockstats to plot things #10757
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
Some ideas for additions:
I would prefer to see both Should we return non-independent fields, such as I find that for bitcoin-related data, the median is often more useful than the average of a distribution. Including |
Because more code => more bugs and more maintenance effort. I prefer: If it's not really needed, why add it? This is perhaps a nice-to-have, but since #8704, Is there a compelling use-case I'm missing here? This seems like a feature only a small subset of users would be interested in, in which case an offline tools seems more appropriate. Sorry - not meaning to be negative, but my default reaction to new RPCs/arguments tends towards NACK unless I can see a compelling and widespread use-case. |
This code pulls each transaction input's previous outpoint in order to compute transaction fees. Replicating that in RPC would require thousands of calls for most blocks. |
Ah yes, of course. EDIT: I'm going to reverse myself again: I don't think +700 lines is worthwhile for something with limited usage for most users. I'm -0 on this. |
Sure, but I mean, removing for example the avgfee or avgfeerate won't safe much code or testing code, just a few lines. Forget I said this, if there's specific functions to remove because nobody will want them, let's remove those and focus on the ones people want. Adding specific things only a few people want can also happen in their own branches, so it's no big deal. The only use case is gather statistics, presumably to plot things, create charts. That is, at least, compelling to me, but I don't think that will have widespread usage. I also don't think all rpc calls have it. Is getchaintxstats, for example, a widespread use case? If that's enough reason not to merge this, it's fine, I can maintain it as a separate branch that I periodically rebase, it is simple enough, so that won't be a big deal. On the other hand, if I can get it reviewed and merged it'll be less work for me in the long run and I also get the review.
Sounds good.
Mhmm, it would be simpler to calculate here from start to end here than from genesis. But it's pretty trivial to write a function in any language that returns the total supply for a given height without access to any historic data. Unless you are talking about discounting op_return outputs or something like that. I don't think this is very interesting here. Perhaps that can be done in getchaintxstats ?
In fact I'm using weight for everything. I should s/size/weight/ and probably also show size separately.
Yeah, the mediantime takes a little bit longer to be calculated but not much and one can always disable anything. In fact, the height and time shouldn't be treated in any special way for being "the x axis" and should be allowed to be disabled like the rest.
This is a good question. This is mostly what I meant by "why not if it's this easy?". re median: yeah, that sounds interesting too, good idea! |
I was thinking of the more trivial version, rather than the |
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, suggestion to use std::set
.
Nit, rename allowed_plot_values
to valid_plot_values
.
Nit, rename getperblockstats
to just getblockstats
?
src/rpc/blockchain.cpp
Outdated
|
||
UniValue getperblockstats(const JSONRPCRequest& request) | ||
{ | ||
std::string str_allowed_plot_values = "minfee,maxfee,totalfee,minfeerate,maxfeerate,avgfee,avgfeerate,txs,ins,outs"; |
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.
Remove.
src/rpc/blockchain.cpp
Outdated
UniValue getperblockstats(const JSONRPCRequest& request) | ||
{ | ||
std::string str_allowed_plot_values = "minfee,maxfee,totalfee,minfeerate,maxfeerate,avgfee,avgfeerate,txs,ins,outs"; | ||
std::vector<std::string> allowed_plot_values; |
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.
std::set<std::string> allowed_plot_values = {"minfee", "maxfee", "..."};
src/rpc/blockchain.cpp
Outdated
{ | ||
std::string str_allowed_plot_values = "minfee,maxfee,totalfee,minfeerate,maxfeerate,avgfee,avgfeerate,txs,ins,outs"; | ||
std::vector<std::string> allowed_plot_values; | ||
boost::split(allowed_plot_values, str_allowed_plot_values, boost::is_any_of(",")); |
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.
Remove.
src/rpc/blockchain.cpp
Outdated
"\nArguments:\n" | ||
"1. \"start\" (numeric, required) The height of the block that starts the window.\n" | ||
"2. \"end\" (numeric, optional) The height of the block that ends the window (default: current tip).\n" | ||
"3. \"plotvalues\" (string, optional) Values to plot (comma separated), default(all): " + str_allowed_plot_values + |
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.
"..." + boost::join(allowed_plot_values, ",")
src/rpc/blockchain.cpp
Outdated
"3. \"plotvalues\" (string, optional) Values to plot (comma separated), default(all): " + str_allowed_plot_values + | ||
"\nResult:\n" | ||
"{\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.
Missing result example.
src/rpc/blockchain.cpp
Outdated
"}\n" | ||
"\nExamples:\n" | ||
+ HelpExampleCli("getperblockstats", "1000 1000 \"minfeerate,avgfeerate\"") | ||
+ HelpExampleRpc("getperblockstats", "1000 1000 \"maxfeerate,avgfeerate\"") |
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.
Duplicate.
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.
One is HelpExampleCli and the other is HelpExampleRpc
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.
Ops sorry, overlooked it.
src/rpc/blockchain.cpp
Outdated
if (request.params.size() > 2) { | ||
str_plot_values = request.params[2].get_str(); | ||
} | ||
std::vector<std::string> plot_values; |
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.
std::set<std::string> plot_values;
if (request.params.size() > 2) {
boost::split(plot_values, request.params[2].get_str(), boost::is_any_of(","));
// only validate in this case
// ...
} else {
plot_values = allowed_plot_values;
}
src/rpc/blockchain.cpp
Outdated
} | ||
} | ||
|
||
static bool IsAllowedPlotValue(const std::string& plot_value, std::vector<std::string>& allowed_plot_values) |
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.
Remove.
src/rpc/blockchain.cpp
Outdated
std::vector<std::string> plot_values; | ||
boost::split(plot_values, str_plot_values, boost::is_any_of(",")); | ||
for (const std::string plot_value : plot_values) { | ||
if (!IsAllowedPlotValue(plot_value, allowed_plot_values)) { |
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.
if (allowed_plot_values.count(plot_value) == 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.
duh, I was so much over-complicating things so much for no good reason...thank you!
Thanks again for the great feedback! @promag I think I solved all your nits except for #10757 (comment) @clarkmoody I think I added most of your suggestions, explicitly excluding anything that involved accumulations neither from height=1 nor from height=start. And for the rest of the redundancies, @jnewbery and @clarkmoody - thanks again for pointing it out -, it's never too late to remove them before merging like a trivial squash and it's never too soon to start saying which ones you would bikesay* out first. Also bikesay the names for the curves and even the order in the list (duplicated for c++ and python). In the meantime, I embraced redundancy since, as said, it will be trivial for me to remove later. And also the pertinent optimizations to skip calculations when plot_values.count("minfee") == 0 or actually only when the extra calculation is more expensive than the searching in plot_values which is a set of strings. For example, we have blockfees, reward, subsidy, complying with consensus rule Which one seems bikesaying in principle. But not in this case. But it is more interesting to propose new ones than to rename or vote for removal IMO. I believe the most interesting addition to this point was utxo_size_inc, which would welcomed some review from people who measures sizes more carefully like @sipa , since this doesn't use GetSerializeSize for Coin intentionally, independently of the optimization to read Coin if available in the utxo before calling RpcGetTx. I'm still not sure what to do with pre/post segwit feerates, does anybody care about the pre ones? which one needs the scale factor? none? REM CalculateTruncatedMedian doesn't need to be a template at this point, but there's no harm being static IMO EDIT: still some TODOs, mostly documentation and pending decisions |
@jtimon no problem. There are some nits to fix but I'll review more in depth later. |
src/policy/feerate.cpp
Outdated
@@ -20,20 +20,22 @@ CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nBytes_) | |||
nSatoshisPerK = 0; | |||
} | |||
|
|||
CAmount CFeeRate::GetFee(size_t nBytes_) const | |||
CAmount CFeeRate::GetTruncatedFee(size_t nBytes_) 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.
Drop _
? Same below.
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.
Well, yes, conserving the old name only saves 1 line of extra disruption. But I guess if we're touching the variable name we should use the new style. just bytes?
src/rpc/blockchain.cpp
Outdated
@@ -685,6 +686,22 @@ UniValue getblockheader(const JSONRPCRequest& request) | |||
return blockheaderToJSON(pblockindex); | |||
} | |||
|
|||
static void ReadBlockCheckPruned(const CBlockIndex* pblockindex, CBlock& block) |
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.
Keep argument order as ReadBlockFromDisk
? Is there a convention for where the output arguments should be?
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.
Not that I know of, but your proposed change sounds good to me.
src/rpc/blockchain.cpp
Outdated
{ | ||
T median; | ||
size_t size = scores.size(); | ||
std::sort(scores.begin(), scores.end()); |
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, could sort only after size == 1
case.
src/rpc/blockchain.cpp
Outdated
} | ||
|
||
// outpoint (needed for the utxo index) + nHeight + fCoinBase | ||
static const size_t PER_UTXO_OVERHEAD = sizeof(COutPoint) + sizeof(uint32_t) + sizeof(bool); |
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.
static constexpr ...
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's the gain? https://stackoverflow.com/a/41132221/935325 says it's the same...
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's the gain? https://stackoverflow.com/a/41132221/935325 says it's the same...
Gain is just that constexpr is more descriptive, and that stackoverflow answer isn't really correct. const
and constexpr
aren't identical even for integers, for example const
is valid here:
static const int X = rand();
where constexpr
would not be:
static constexpr int X = rand();
Also that stackoverflow answer is relying on special case treatment for integers that doesn't apply to other types like floats. constexpr
is just better for declaring compile time constants that const
, so we should prefer it.
src/rpc/blockchain.cpp
Outdated
ReadBlockCheckPruned(pindex, block); | ||
|
||
for (const auto& tx : block.vtx) { | ||
|
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.
Remove empty line.
src/rpc/blockchain.cpp
Outdated
map_stats[plot_value] = UniValue(UniValue::VARR); | ||
} | ||
|
||
CBlockIndex* pindex = chainActive[end]; |
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.
Remove.
src/rpc/blockchain.cpp
Outdated
|
||
CBlockIndex* pindex = chainActive[end]; | ||
for (int i = end; i >= start; i--) { | ||
UpdateBlockStats(pindex, plot_values, map_stats); |
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.
UpdateBlockStats(chainActive[i], ...);
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 will be slightly less efficient, 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.
I guess it takes few more cycles but non critical code should be cleaner?
src/rpc/blockchain.cpp
Outdated
"\nArguments:\n" | ||
"1. \"start\" (numeric, required) The height of the block that starts the window.\n" | ||
"2. \"end\" (numeric, optional) The height of the block that ends the window (default: current tip).\n" | ||
"3. \"plotvalues\" (string, optional) Values to plot (comma separated), default(all): " + boost::join(valid_plot_values, ",") + |
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.
Replace plotvalues
with stats
? Also, 3rd argument could be object options
?
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.
Isn't the string simpler?
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.
Ignore options
suggestion.
src/rpc/blockchain.cpp
Outdated
int end; | ||
if (request.params.size() > 1) { | ||
end = request.params[1].get_int(); | ||
if (end < 0 || end > chainActive.Height()) { |
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, negative block could mean end = height - end
to avoid early blocks (not new concept here I believe)?
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.
Mhmm, interesting. To be clear you mean start=-10 end=200 would be equivalent to start=190 end=200, right?
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, I meant negative values are relative to the tip. To get the stats for the last 10 blocks you would pass start = -10 without querying the current block height.
Here are some images generated using this branch in combination with (WIP): https://github.com/jtimon/rpc-explorer GUI detail: GUI detail zoom: Hide some: Hide more: Fees: Utxo size increase: |
79d9907
to
90c7264
Compare
Without the documentation for the result it was impossible to distinguish a weird choice to spring discussion from an implementation mistake. Removed the other TODO comments. More cleanups can be done, specially in the tests if we go further with #10757 (comment) and not calculate in inverse order (there's no point if we don't get the slight optimization). |
90c7264
to
33d2bda
Compare
Needed rebase. |
Just wanted to say that this would be massively helpful to track statistics. I hope this finds it's way into a release soon. |
8bc1d6a
to
b2d93e4
Compare
Reversed the order of the values to the natural one, since as discussed the optimization of doing fetching the blocks in reverse order is not worth the loss in clarity of the code. |
Perhaps a better name for <stat>_old is <stat>_virtual, _virt or _v. Or perhaps prepend it with "v" just like the tx size in the output of For example:
etc. |
I just finished calling Btw, if anyone is interested in the dataset I can share it. Just convo me at freenode irc (nick: "trippysalmon"). It includes some other stats as well, like rolling average hashrates. |
test/functional/rpc_getblockstats.py
Outdated
assert_raises_rpc_error(-5, 'Block not found', self.nodes[0].getblockstats, | ||
hash_or_height='000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f') | ||
|
||
|
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.
Linter error:
W293 blank line contains whitespace.
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.
Fixed
cedac47
to
563eee9
Compare
Lightly tested ACK 563eee9. |
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 563eee92c9ddc5b537fca1ce08bce811d97aed97 w/ minor nits
src/rpc/blockchain.cpp
Outdated
" ,...\n" | ||
" ]\n" | ||
"\nResult: (all values are in reverse order height-wise)\n" | ||
"{ (json object)\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.
Due to two escapes in below lines, this needs to remove two spaces for alignment.
const uint256 hash(uint256S(strHash)); | ||
pindex = LookupBlockIndex(hash); | ||
if (!pindex) { | ||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); |
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.
Just a note here. In
bitcoin/src/rpc/blockchain.cpp
Lines 809 to 818 in 4cfe17c
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) | |
throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)"); | |
if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) | |
// Block not found on disk. This could be because we have the block | |
// header in our index but don't have the block (for example if a | |
// non-whitelisted node sends us an unrequested long chain of valid | |
// blocks, we add the headers to our index, but don't accept the | |
// block). | |
throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk"); |
RPC_MISC_ERROR
is used, while RPC_INVALID_ADDRESS_OR_KEY
is used here. Not sure which is better, but I think they should both use the same error type. (This PR touches the other one so could easily tweak, I think.)
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 disagree. If the header is not found, that means the request was invalid, hence RPC_INVALID ADDRESS_OR KEY (key loosely taken to mean request argument, I take it). Whereas if the header is known but the block is not known, I do consider that to be a different error.
In #13144, I introduce RPC_DATA_UNAVAILABLE, which may be more appropriate than RPC_MISC in the latter case.
totalfee += txfee; | ||
|
||
// New feerate uses satoshis per virtual byte instead of per serialized byte | ||
CAmount feerate = weight ? (txfee * WITNESS_SCALE_FACTOR) / weight : 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.
May be ok, but I think (txfee * WITNESS_SCALE_FACTOR) / (weight + WITNESS_SCALE_FACTOR - 1)
is precisely accurate while the above will have truncation errors sometimes.
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.
That equation has truncated errors. Consider a tx with weight 3 and fee 100. The vsize is 1, so the fee rate should be 1, but your equation would give (100 * 4) / 6 = 66.
You point out correctly though that vsize is computed incorrectly here by rounding down rather than up. This should use GetVirtualTransactionSize()
.
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.
Sorry, I don't follow. This is using GetTransactionWeight() which does ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)
GetVirtualTransactionSize does (std::max(nWeight, nSigOpCost * nBytesPerSigOp) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR
But I'm not sure why would we prefer that here.
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.
Sorry, I think I got things mixed up.
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.
The fee rate for a tx with weight 3 and fee 100 is the same as if there were 100 such tx's. That would have weight 300 or vsize 75, and fee 10,000, for a fee rate of 10,000/75 or 133.3, not 1, 100, or 66. :) Formula looks fine to me, though I guess estimatefee uses fee/vkbyte rather than fee/byte, which would be (txfee * WITNESS_SCALE_FACTOR * 1000) / weight
.
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.
Well, we can move from sat/vbyte to sat/vkbyte, sure. I t should be a simple change if people prefer that.
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.
ACK 563eee92c9ddc5b537fca1ce08bce811d97aed97 modulo nits
src/rpc/blockchain.cpp
Outdated
"\nIt won't work for some heights with pruning.\n" | ||
"\nIt won't work without -txindex for utxo_size_inc, *fee or *feerate stats.\n" | ||
"\nArguments:\n" | ||
"1. \"hash_or_height\" (string or numeric, required) The block hash or height of the target block. If height, negative values count back from the current tip\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.
But, negative values don't count back from the current tip, they give an error?
src/rpc/blockchain.cpp
Outdated
|
||
static UniValue getblockstats(const JSONRPCRequest& request) | ||
{ | ||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) |
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.
Multiline if statement should have braces.
src/rpc/blockchain.cpp
Outdated
" \"time\", (string, optional) Selected statistic\n" | ||
" ,...\n" | ||
" ]\n" | ||
"\nResult: (all values are in reverse order height-wise)\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.
"(all values are in reverse order height-wise)" is outdated now that this only does one block's stats, I think? If it's not, it doesn't make sense to me...
Includes commit from Anthony Towns @ajtowns: Tests: Save and load block and corresponding expected statistics
Fixed help nits (also made other improvements, some other things in the help were ugly). |
41d0476 Tests: Add data file (Anthony Towns) 4cbfb6a Tests: Test new getblockstats RPC (Jorge Timón) 35e77a0 RPC: Introduce getblockstats (Jorge Timón) cda8e36 Refactor: RPC: Separate GetBlockChecked() from getblock() (Jorge Timón) Pull request description: It returns per block statistics about several things. It should be easy to add more if people think of other things to add or remove some if I went too far (but once written, why not keep it? EDIT: answer: not to test or maintain them). The currently available options are: minfee,maxfee,totalfee,minfeerate,maxfeerate,avgfee,avgfeerate,txs,ins,outs (EDIT: see updated list in the rpc call documentation) For the x axis, one can use height or block.nTime (I guess I could add mediantime if there's interest [EDIT: nobody showed interest but I implemented mediantime nonetheless, in fact there's no distinction between x or y axis anymore, that's for the caller to judge]). To calculate fees, -txindex is required. Tree-SHA512: 2b2787a3c7dc4a11df1fce62c8a4c748f5347d7f7104205d5f0962ffec1e0370c825b49fd4d58ce8ce86bf39d8453f698bcd46206eea505f077541ca7d59b18c
… pruned or not e9a1881 refactor: add a function for determining if a block is pruned or not (Karl-Johan Alm) Pull request description: The check for whether a block is pruned or not is sufficiently obscure that it deserves a macro. It is also used in 2 places, ~~with more coming, e.g. #10757~~ (turns out it was a move, not an addition). Tree-SHA512: b9aeb60663e1d1196df5371d5aa00b32ff5d4cdea6a77e4b566f28115cce09570c18e45e4b81a4033f67c4135c8e32c027f67bae3b75c2ea4564285578a3f4dd
41d0476 Tests: Add data file (Anthony Towns) 4cbfb6a Tests: Test new getblockstats RPC (Jorge Timón) 35e77a0 RPC: Introduce getblockstats (Jorge Timón) cda8e36 Refactor: RPC: Separate GetBlockChecked() from getblock() (Jorge Timón) Pull request description: It returns per block statistics about several things. It should be easy to add more if people think of other things to add or remove some if I went too far (but once written, why not keep it? EDIT: answer: not to test or maintain them). The currently available options are: minfee,maxfee,totalfee,minfeerate,maxfeerate,avgfee,avgfeerate,txs,ins,outs (EDIT: see updated list in the rpc call documentation) For the x axis, one can use height or block.nTime (I guess I could add mediantime if there's interest [EDIT: nobody showed interest but I implemented mediantime nonetheless, in fact there's no distinction between x or y axis anymore, that's for the caller to judge]). To calculate fees, -txindex is required. Tree-SHA512: 2b2787a3c7dc4a11df1fce62c8a4c748f5347d7f7104205d5f0962ffec1e0370c825b49fd4d58ce8ce86bf39d8453f698bcd46206eea505f077541ca7d59b18c
41d0476 Tests: Add data file (Anthony Towns) 4cbfb6a Tests: Test new getblockstats RPC (Jorge Timón) 35e77a0 RPC: Introduce getblockstats (Jorge Timón) cda8e36 Refactor: RPC: Separate GetBlockChecked() from getblock() (Jorge Timón) Pull request description: It returns per block statistics about several things. It should be easy to add more if people think of other things to add or remove some if I went too far (but once written, why not keep it? EDIT: answer: not to test or maintain them). The currently available options are: minfee,maxfee,totalfee,minfeerate,maxfeerate,avgfee,avgfeerate,txs,ins,outs (EDIT: see updated list in the rpc call documentation) For the x axis, one can use height or block.nTime (I guess I could add mediantime if there's interest [EDIT: nobody showed interest but I implemented mediantime nonetheless, in fact there's no distinction between x or y axis anymore, that's for the caller to judge]). To calculate fees, -txindex is required. Tree-SHA512: 2b2787a3c7dc4a11df1fce62c8a4c748f5347d7f7104205d5f0962ffec1e0370c825b49fd4d58ce8ce86bf39d8453f698bcd46206eea505f077541ca7d59b18c
* Merge bitcoin#10757: RPC: Introduce getblockstats to plot things 41d0476 Tests: Add data file (Anthony Towns) 4cbfb6a Tests: Test new getblockstats RPC (Jorge Timón) 35e77a0 RPC: Introduce getblockstats (Jorge Timón) cda8e36 Refactor: RPC: Separate GetBlockChecked() from getblock() (Jorge Timón) Pull request description: It returns per block statistics about several things. It should be easy to add more if people think of other things to add or remove some if I went too far (but once written, why not keep it? EDIT: answer: not to test or maintain them). The currently available options are: minfee,maxfee,totalfee,minfeerate,maxfeerate,avgfee,avgfeerate,txs,ins,outs (EDIT: see updated list in the rpc call documentation) For the x axis, one can use height or block.nTime (I guess I could add mediantime if there's interest [EDIT: nobody showed interest but I implemented mediantime nonetheless, in fact there's no distinction between x or y axis anymore, that's for the caller to judge]). To calculate fees, -txindex is required. Tree-SHA512: 2b2787a3c7dc4a11df1fce62c8a4c748f5347d7f7104205d5f0962ffec1e0370c825b49fd4d58ce8ce86bf39d8453f698bcd46206eea505f077541ca7d59b18c * Replace get_mocktime() usage with self.mocktime
…hpay#3058) * Merge bitcoin#10757: RPC: Introduce getblockstats to plot things 41d0476 Tests: Add data file (Anthony Towns) 4cbfb6a Tests: Test new getblockstats RPC (Jorge Timón) 35e77a0 RPC: Introduce getblockstats (Jorge Timón) cda8e36 Refactor: RPC: Separate GetBlockChecked() from getblock() (Jorge Timón) Pull request description: It returns per block statistics about several things. It should be easy to add more if people think of other things to add or remove some if I went too far (but once written, why not keep it? EDIT: answer: not to test or maintain them). The currently available options are: minfee,maxfee,totalfee,minfeerate,maxfeerate,avgfee,avgfeerate,txs,ins,outs (EDIT: see updated list in the rpc call documentation) For the x axis, one can use height or block.nTime (I guess I could add mediantime if there's interest [EDIT: nobody showed interest but I implemented mediantime nonetheless, in fact there's no distinction between x or y axis anymore, that's for the caller to judge]). To calculate fees, -txindex is required. Tree-SHA512: 2b2787a3c7dc4a11df1fce62c8a4c748f5347d7f7104205d5f0962ffec1e0370c825b49fd4d58ce8ce86bf39d8453f698bcd46206eea505f077541ca7d59b18c * Replace get_mocktime() usage with self.mocktime
…lock is pruned or not e9a1881 refactor: add a function for determining if a block is pruned or not (Karl-Johan Alm) Pull request description: The check for whether a block is pruned or not is sufficiently obscure that it deserves a macro. It is also used in 2 places, ~~with more coming, e.g. bitcoin#10757~~ (turns out it was a move, not an addition). Tree-SHA512: b9aeb60663e1d1196df5371d5aa00b32ff5d4cdea6a77e4b566f28115cce09570c18e45e4b81a4033f67c4135c8e32c027f67bae3b75c2ea4564285578a3f4dd
…lock is pruned or not e9a1881 refactor: add a function for determining if a block is pruned or not (Karl-Johan Alm) Pull request description: The check for whether a block is pruned or not is sufficiently obscure that it deserves a macro. It is also used in 2 places, ~~with more coming, e.g. bitcoin#10757~~ (turns out it was a move, not an addition). Tree-SHA512: b9aeb60663e1d1196df5371d5aa00b32ff5d4cdea6a77e4b566f28115cce09570c18e45e4b81a4033f67c4135c8e32c027f67bae3b75c2ea4564285578a3f4dd
It returns per block statistics about several things. It should be easy to add more if people think of other things to add or remove some if I went too far (but once written, why not keep it? EDIT: answer: not to test or maintain them).
The currently available options are: minfee,maxfee,totalfee,minfeerate,maxfeerate,avgfee,avgfeerate,txs,ins,outs (EDIT: see updated list in the rpc call documentation)
For the x axis, one can use height or block.nTime (I guess I could add mediantime if there's interest [EDIT: nobody showed interest but I implemented mediantime nonetheless, in fact there's no distinction between x or y axis anymore, that's for the caller to judge]).
To calculate fees, -txindex is required.