Replace median fee rate with feerate percentiles
Removes medianfeerate result from getblockstats. Adds feerate_percentiles which give the feerate of the 10th, 25th, 50th, 75th, and 90th percentile weight unit in the block.
This commit is contained in:
parent
df9f712746
commit
4b7091a842
5 changed files with 162 additions and 12 deletions
|
@ -1640,6 +1640,35 @@ static T CalculateTruncatedMedian(std::vector<T>& scores)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight)
|
||||||
|
{
|
||||||
|
if (scores.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(scores.begin(), scores.end());
|
||||||
|
|
||||||
|
// 10th, 25th, 50th, 75th, and 90th percentile weight units.
|
||||||
|
const double weights[NUM_GETBLOCKSTATS_PERCENTILES] = {
|
||||||
|
total_weight / 10.0, total_weight / 4.0, total_weight / 2.0, (total_weight * 3.0) / 4.0, (total_weight * 9.0) / 10.0
|
||||||
|
};
|
||||||
|
|
||||||
|
int64_t next_percentile_index = 0;
|
||||||
|
int64_t cumulative_weight = 0;
|
||||||
|
for (const auto& element : scores) {
|
||||||
|
cumulative_weight += element.second;
|
||||||
|
while (next_percentile_index < NUM_GETBLOCKSTATS_PERCENTILES && cumulative_weight >= weights[next_percentile_index]) {
|
||||||
|
result[next_percentile_index] = element.first;
|
||||||
|
++next_percentile_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill any remaining percentiles with the last value.
|
||||||
|
for (int64_t i = next_percentile_index; i < NUM_GETBLOCKSTATS_PERCENTILES; i++) {
|
||||||
|
result[i] = scores.back().first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline bool SetHasKeys(const std::set<T>& set) {return false;}
|
static inline bool SetHasKeys(const std::set<T>& set) {return false;}
|
||||||
template<typename T, typename Tk, typename... Args>
|
template<typename T, typename Tk, typename... Args>
|
||||||
|
@ -1673,13 +1702,19 @@ static UniValue getblockstats(const JSONRPCRequest& request)
|
||||||
" \"avgfeerate\": xxxxx, (numeric) Average feerate (in satoshis per virtual byte)\n"
|
" \"avgfeerate\": xxxxx, (numeric) Average feerate (in satoshis per virtual byte)\n"
|
||||||
" \"avgtxsize\": xxxxx, (numeric) Average transaction size\n"
|
" \"avgtxsize\": xxxxx, (numeric) Average transaction size\n"
|
||||||
" \"blockhash\": xxxxx, (string) The block hash (to check for potential reorgs)\n"
|
" \"blockhash\": xxxxx, (string) The block hash (to check for potential reorgs)\n"
|
||||||
|
" \"feerate_percentiles\": [ (array of numeric) Feerates at the 10th, 25th, 50th, 75th, and 90th percentile weight unit (in satoshis per virtual byte)\n"
|
||||||
|
" \"10th_percentile_feerate\", (numeric) The 10th percentile feerate\n"
|
||||||
|
" \"25th_percentile_feerate\", (numeric) The 25th percentile feerate\n"
|
||||||
|
" \"50th_percentile_feerate\", (numeric) The 50th percentile feerate\n"
|
||||||
|
" \"75th_percentile_feerate\", (numeric) The 75th percentile feerate\n"
|
||||||
|
" \"90th_percentile_feerate\", (numeric) The 90th percentile feerate\n"
|
||||||
|
" ],\n"
|
||||||
" \"height\": xxxxx, (numeric) The height of the block\n"
|
" \"height\": xxxxx, (numeric) The height of the block\n"
|
||||||
" \"ins\": xxxxx, (numeric) The number of inputs (excluding coinbase)\n"
|
" \"ins\": xxxxx, (numeric) The number of inputs (excluding coinbase)\n"
|
||||||
" \"maxfee\": xxxxx, (numeric) Maximum fee in the block\n"
|
" \"maxfee\": xxxxx, (numeric) Maximum fee in the block\n"
|
||||||
" \"maxfeerate\": xxxxx, (numeric) Maximum feerate (in satoshis per virtual byte)\n"
|
" \"maxfeerate\": xxxxx, (numeric) Maximum feerate (in satoshis per virtual byte)\n"
|
||||||
" \"maxtxsize\": xxxxx, (numeric) Maximum transaction size\n"
|
" \"maxtxsize\": xxxxx, (numeric) Maximum transaction size\n"
|
||||||
" \"medianfee\": xxxxx, (numeric) Truncated median fee in the block\n"
|
" \"medianfee\": xxxxx, (numeric) Truncated median fee in the block\n"
|
||||||
" \"medianfeerate\": xxxxx, (numeric) Truncated median feerate (in satoshis per virtual byte)\n"
|
|
||||||
" \"mediantime\": xxxxx, (numeric) The block median time past\n"
|
" \"mediantime\": xxxxx, (numeric) The block median time past\n"
|
||||||
" \"mediantxsize\": xxxxx, (numeric) Truncated median transaction size\n"
|
" \"mediantxsize\": xxxxx, (numeric) Truncated median transaction size\n"
|
||||||
" \"minfee\": xxxxx, (numeric) Minimum fee in the block\n"
|
" \"minfee\": xxxxx, (numeric) Minimum fee in the block\n"
|
||||||
|
@ -1747,13 +1782,13 @@ static UniValue getblockstats(const JSONRPCRequest& request)
|
||||||
const bool do_all = stats.size() == 0; // Calculate everything if nothing selected (default)
|
const bool do_all = stats.size() == 0; // Calculate everything if nothing selected (default)
|
||||||
const bool do_mediantxsize = do_all || stats.count("mediantxsize") != 0;
|
const bool do_mediantxsize = do_all || stats.count("mediantxsize") != 0;
|
||||||
const bool do_medianfee = do_all || stats.count("medianfee") != 0;
|
const bool do_medianfee = do_all || stats.count("medianfee") != 0;
|
||||||
const bool do_medianfeerate = do_all || stats.count("medianfeerate") != 0;
|
const bool do_feerate_percentiles = do_all || stats.count("feerate_percentiles") != 0;
|
||||||
const bool loop_inputs = do_all || do_medianfee || do_medianfeerate ||
|
const bool loop_inputs = do_all || do_medianfee || do_feerate_percentiles ||
|
||||||
SetHasKeys(stats, "utxo_size_inc", "totalfee", "avgfee", "avgfeerate", "minfee", "maxfee", "minfeerate", "maxfeerate");
|
SetHasKeys(stats, "utxo_size_inc", "totalfee", "avgfee", "avgfeerate", "minfee", "maxfee", "minfeerate", "maxfeerate");
|
||||||
const bool loop_outputs = do_all || loop_inputs || stats.count("total_out");
|
const bool loop_outputs = do_all || loop_inputs || stats.count("total_out");
|
||||||
const bool do_calculate_size = do_mediantxsize ||
|
const bool do_calculate_size = do_mediantxsize ||
|
||||||
SetHasKeys(stats, "total_size", "avgtxsize", "mintxsize", "maxtxsize", "swtotal_size");
|
SetHasKeys(stats, "total_size", "avgtxsize", "mintxsize", "maxtxsize", "swtotal_size");
|
||||||
const bool do_calculate_weight = do_all || SetHasKeys(stats, "total_weight", "avgfeerate", "swtotal_weight", "avgfeerate", "medianfeerate", "minfeerate", "maxfeerate");
|
const bool do_calculate_weight = do_all || SetHasKeys(stats, "total_weight", "avgfeerate", "swtotal_weight", "avgfeerate", "feerate_percentiles", "minfeerate", "maxfeerate");
|
||||||
const bool do_calculate_sw = do_all || SetHasKeys(stats, "swtxs", "swtotal_size", "swtotal_weight");
|
const bool do_calculate_sw = do_all || SetHasKeys(stats, "swtxs", "swtotal_size", "swtotal_weight");
|
||||||
|
|
||||||
CAmount maxfee = 0;
|
CAmount maxfee = 0;
|
||||||
|
@ -1773,7 +1808,7 @@ static UniValue getblockstats(const JSONRPCRequest& request)
|
||||||
int64_t total_weight = 0;
|
int64_t total_weight = 0;
|
||||||
int64_t utxo_size_inc = 0;
|
int64_t utxo_size_inc = 0;
|
||||||
std::vector<CAmount> fee_array;
|
std::vector<CAmount> fee_array;
|
||||||
std::vector<CAmount> feerate_array;
|
std::vector<std::pair<CAmount, int64_t>> feerate_array;
|
||||||
std::vector<int64_t> txsize_array;
|
std::vector<int64_t> txsize_array;
|
||||||
|
|
||||||
for (const auto& tx : block.vtx) {
|
for (const auto& tx : block.vtx) {
|
||||||
|
@ -1848,26 +1883,34 @@ static UniValue getblockstats(const JSONRPCRequest& request)
|
||||||
|
|
||||||
// New feerate uses satoshis per virtual byte instead of per serialized byte
|
// New feerate uses satoshis per virtual byte instead of per serialized byte
|
||||||
CAmount feerate = weight ? (txfee * WITNESS_SCALE_FACTOR) / weight : 0;
|
CAmount feerate = weight ? (txfee * WITNESS_SCALE_FACTOR) / weight : 0;
|
||||||
if (do_medianfeerate) {
|
if (do_feerate_percentiles) {
|
||||||
feerate_array.push_back(feerate);
|
feerate_array.emplace_back(std::make_pair(feerate, weight));
|
||||||
}
|
}
|
||||||
maxfeerate = std::max(maxfeerate, feerate);
|
maxfeerate = std::max(maxfeerate, feerate);
|
||||||
minfeerate = std::min(minfeerate, feerate);
|
minfeerate = std::min(minfeerate, feerate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CAmount feerate_percentiles[NUM_GETBLOCKSTATS_PERCENTILES] = { 0 };
|
||||||
|
CalculatePercentilesByWeight(feerate_percentiles, feerate_array, total_weight);
|
||||||
|
|
||||||
|
UniValue feerates_res(UniValue::VARR);
|
||||||
|
for (int64_t i = 0; i < NUM_GETBLOCKSTATS_PERCENTILES; i++) {
|
||||||
|
feerates_res.push_back(feerate_percentiles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
UniValue ret_all(UniValue::VOBJ);
|
UniValue ret_all(UniValue::VOBJ);
|
||||||
ret_all.pushKV("avgfee", (block.vtx.size() > 1) ? totalfee / (block.vtx.size() - 1) : 0);
|
ret_all.pushKV("avgfee", (block.vtx.size() > 1) ? totalfee / (block.vtx.size() - 1) : 0);
|
||||||
ret_all.pushKV("avgfeerate", total_weight ? (totalfee * WITNESS_SCALE_FACTOR) / total_weight : 0); // Unit: sat/vbyte
|
ret_all.pushKV("avgfeerate", total_weight ? (totalfee * WITNESS_SCALE_FACTOR) / total_weight : 0); // Unit: sat/vbyte
|
||||||
ret_all.pushKV("avgtxsize", (block.vtx.size() > 1) ? total_size / (block.vtx.size() - 1) : 0);
|
ret_all.pushKV("avgtxsize", (block.vtx.size() > 1) ? total_size / (block.vtx.size() - 1) : 0);
|
||||||
ret_all.pushKV("blockhash", pindex->GetBlockHash().GetHex());
|
ret_all.pushKV("blockhash", pindex->GetBlockHash().GetHex());
|
||||||
|
ret_all.pushKV("feerate_percentiles", feerates_res);
|
||||||
ret_all.pushKV("height", (int64_t)pindex->nHeight);
|
ret_all.pushKV("height", (int64_t)pindex->nHeight);
|
||||||
ret_all.pushKV("ins", inputs);
|
ret_all.pushKV("ins", inputs);
|
||||||
ret_all.pushKV("maxfee", maxfee);
|
ret_all.pushKV("maxfee", maxfee);
|
||||||
ret_all.pushKV("maxfeerate", maxfeerate);
|
ret_all.pushKV("maxfeerate", maxfeerate);
|
||||||
ret_all.pushKV("maxtxsize", maxtxsize);
|
ret_all.pushKV("maxtxsize", maxtxsize);
|
||||||
ret_all.pushKV("medianfee", CalculateTruncatedMedian(fee_array));
|
ret_all.pushKV("medianfee", CalculateTruncatedMedian(fee_array));
|
||||||
ret_all.pushKV("medianfeerate", CalculateTruncatedMedian(feerate_array));
|
|
||||||
ret_all.pushKV("mediantime", pindex->GetMedianTimePast());
|
ret_all.pushKV("mediantime", pindex->GetMedianTimePast());
|
||||||
ret_all.pushKV("mediantxsize", CalculateTruncatedMedian(txsize_array));
|
ret_all.pushKV("mediantxsize", CalculateTruncatedMedian(txsize_array));
|
||||||
ret_all.pushKV("minfee", (minfee == MAX_MONEY) ? 0 : minfee);
|
ret_all.pushKV("minfee", (minfee == MAX_MONEY) ? 0 : minfee);
|
||||||
|
|
|
@ -5,10 +5,16 @@
|
||||||
#ifndef BITCOIN_RPC_BLOCKCHAIN_H
|
#ifndef BITCOIN_RPC_BLOCKCHAIN_H
|
||||||
#define BITCOIN_RPC_BLOCKCHAIN_H
|
#define BITCOIN_RPC_BLOCKCHAIN_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <amount.h>
|
||||||
|
|
||||||
class CBlock;
|
class CBlock;
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
class UniValue;
|
class UniValue;
|
||||||
|
|
||||||
|
static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the difficulty of the net wrt to the given block index, or the chain tip if
|
* Get the difficulty of the net wrt to the given block index, or the chain tip if
|
||||||
* not provided.
|
* not provided.
|
||||||
|
@ -33,4 +39,7 @@ UniValue mempoolToJSON(bool fVerbose = false);
|
||||||
/** Block header to JSON */
|
/** Block header to JSON */
|
||||||
UniValue blockheaderToJSON(const CBlockIndex* blockindex);
|
UniValue blockheaderToJSON(const CBlockIndex* blockindex);
|
||||||
|
|
||||||
|
/** Used by getblockstats to get feerates at different percentiles by weight */
|
||||||
|
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
|
|
||||||
|
#include <rpc/blockchain.h>
|
||||||
|
|
||||||
UniValue CallRPC(std::string args)
|
UniValue CallRPC(std::string args)
|
||||||
{
|
{
|
||||||
std::vector<std::string> vArgs;
|
std::vector<std::string> vArgs;
|
||||||
|
@ -336,4 +338,82 @@ BOOST_AUTO_TEST_CASE(rpc_convert_values_generatetoaddress)
|
||||||
BOOST_CHECK_EQUAL(result[2].get_int(), 9);
|
BOOST_CHECK_EQUAL(result[2].get_int(), 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(rpc_getblockstats_calculate_percentiles_by_weight)
|
||||||
|
{
|
||||||
|
int64_t total_weight = 200;
|
||||||
|
std::vector<std::pair<CAmount, int64_t>> feerates;
|
||||||
|
CAmount result[NUM_GETBLOCKSTATS_PERCENTILES] = { 0 };
|
||||||
|
|
||||||
|
for (int64_t i = 0; i < 100; i++) {
|
||||||
|
feerates.emplace_back(std::make_pair(1 ,1));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int64_t i = 0; i < 100; i++) {
|
||||||
|
feerates.emplace_back(std::make_pair(2 ,1));
|
||||||
|
}
|
||||||
|
|
||||||
|
CalculatePercentilesByWeight(result, feerates, total_weight);
|
||||||
|
BOOST_CHECK_EQUAL(result[0], 1);
|
||||||
|
BOOST_CHECK_EQUAL(result[1], 1);
|
||||||
|
BOOST_CHECK_EQUAL(result[2], 1);
|
||||||
|
BOOST_CHECK_EQUAL(result[3], 2);
|
||||||
|
BOOST_CHECK_EQUAL(result[4], 2);
|
||||||
|
|
||||||
|
// Test with more pairs, and two pairs overlapping 2 percentiles.
|
||||||
|
total_weight = 100;
|
||||||
|
CAmount result2[NUM_GETBLOCKSTATS_PERCENTILES] = { 0 };
|
||||||
|
feerates.clear();
|
||||||
|
|
||||||
|
feerates.emplace_back(std::make_pair(1, 9));
|
||||||
|
feerates.emplace_back(std::make_pair(2 , 16)); //10th + 25th percentile
|
||||||
|
feerates.emplace_back(std::make_pair(4 ,50)); //50th + 75th percentile
|
||||||
|
feerates.emplace_back(std::make_pair(5 ,10));
|
||||||
|
feerates.emplace_back(std::make_pair(9 ,15)); // 90th percentile
|
||||||
|
|
||||||
|
CalculatePercentilesByWeight(result2, feerates, total_weight);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(result2[0], 2);
|
||||||
|
BOOST_CHECK_EQUAL(result2[1], 2);
|
||||||
|
BOOST_CHECK_EQUAL(result2[2], 4);
|
||||||
|
BOOST_CHECK_EQUAL(result2[3], 4);
|
||||||
|
BOOST_CHECK_EQUAL(result2[4], 9);
|
||||||
|
|
||||||
|
// Same test as above, but one of the percentile-overlapping pairs is split in 2.
|
||||||
|
total_weight = 100;
|
||||||
|
CAmount result3[NUM_GETBLOCKSTATS_PERCENTILES] = { 0 };
|
||||||
|
feerates.clear();
|
||||||
|
|
||||||
|
feerates.emplace_back(std::make_pair(1, 9));
|
||||||
|
feerates.emplace_back(std::make_pair(2 , 11)); // 10th percentile
|
||||||
|
feerates.emplace_back(std::make_pair(2 , 5)); // 25th percentile
|
||||||
|
feerates.emplace_back(std::make_pair(4 ,50)); //50th + 75th percentile
|
||||||
|
feerates.emplace_back(std::make_pair(5 ,10));
|
||||||
|
feerates.emplace_back(std::make_pair(9 ,15)); // 90th percentile
|
||||||
|
|
||||||
|
CalculatePercentilesByWeight(result3, feerates, total_weight);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(result3[0], 2);
|
||||||
|
BOOST_CHECK_EQUAL(result3[1], 2);
|
||||||
|
BOOST_CHECK_EQUAL(result3[2], 4);
|
||||||
|
BOOST_CHECK_EQUAL(result3[3], 4);
|
||||||
|
BOOST_CHECK_EQUAL(result3[4], 9);
|
||||||
|
|
||||||
|
// Test with one transaction spanning all percentiles.
|
||||||
|
total_weight = 104;
|
||||||
|
CAmount result4[NUM_GETBLOCKSTATS_PERCENTILES] = { 0 };
|
||||||
|
feerates.clear();
|
||||||
|
|
||||||
|
feerates.emplace_back(std::make_pair(1, 100));
|
||||||
|
feerates.emplace_back(std::make_pair(2, 1));
|
||||||
|
feerates.emplace_back(std::make_pair(3, 1));
|
||||||
|
feerates.emplace_back(std::make_pair(3, 1));
|
||||||
|
feerates.emplace_back(std::make_pair(999999, 1));
|
||||||
|
|
||||||
|
CalculatePercentilesByWeight(result4, feerates, total_weight);
|
||||||
|
|
||||||
|
for (int64_t i = 0; i < NUM_GETBLOCKSTATS_PERCENTILES; i++) {
|
||||||
|
BOOST_CHECK_EQUAL(result4[i], 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
@ -112,13 +112,19 @@
|
||||||
"avgfeerate": 0,
|
"avgfeerate": 0,
|
||||||
"avgtxsize": 0,
|
"avgtxsize": 0,
|
||||||
"blockhash": "1d7fe80f19d28b8e712af0399ac84006db753441f3033111b3a8d610afab364f",
|
"blockhash": "1d7fe80f19d28b8e712af0399ac84006db753441f3033111b3a8d610afab364f",
|
||||||
|
"feerate_percentiles": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
"height": 101,
|
"height": 101,
|
||||||
"ins": 0,
|
"ins": 0,
|
||||||
"maxfee": 0,
|
"maxfee": 0,
|
||||||
"maxfeerate": 0,
|
"maxfeerate": 0,
|
||||||
"maxtxsize": 0,
|
"maxtxsize": 0,
|
||||||
"medianfee": 0,
|
"medianfee": 0,
|
||||||
"medianfeerate": 0,
|
|
||||||
"mediantime": 1525107242,
|
"mediantime": 1525107242,
|
||||||
"mediantxsize": 0,
|
"mediantxsize": 0,
|
||||||
"minfee": 0,
|
"minfee": 0,
|
||||||
|
@ -144,12 +150,18 @@
|
||||||
"avgtxsize": 187,
|
"avgtxsize": 187,
|
||||||
"blockhash": "4e21a43675d7a41cb6b944e068c5bcd0a677baf658d9ebe021ae2d2f99397ccc",
|
"blockhash": "4e21a43675d7a41cb6b944e068c5bcd0a677baf658d9ebe021ae2d2f99397ccc",
|
||||||
"height": 102,
|
"height": 102,
|
||||||
|
"feerate_percentiles": [
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
20
|
||||||
|
],
|
||||||
"ins": 1,
|
"ins": 1,
|
||||||
"maxfee": 3760,
|
"maxfee": 3760,
|
||||||
"maxfeerate": 20,
|
"maxfeerate": 20,
|
||||||
"maxtxsize": 187,
|
"maxtxsize": 187,
|
||||||
"medianfee": 3760,
|
"medianfee": 3760,
|
||||||
"medianfeerate": 20,
|
|
||||||
"mediantime": 1525107242,
|
"mediantime": 1525107242,
|
||||||
"mediantxsize": 187,
|
"mediantxsize": 187,
|
||||||
"minfee": 3760,
|
"minfee": 3760,
|
||||||
|
@ -174,13 +186,19 @@
|
||||||
"avgfeerate": 109,
|
"avgfeerate": 109,
|
||||||
"avgtxsize": 228,
|
"avgtxsize": 228,
|
||||||
"blockhash": "22d9b8b9c2a37c81515f3fc84f7241f6c07dbcea85ef16b00bcc33ae400a030f",
|
"blockhash": "22d9b8b9c2a37c81515f3fc84f7241f6c07dbcea85ef16b00bcc33ae400a030f",
|
||||||
|
"feerate_percentiles": [
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
300,
|
||||||
|
300
|
||||||
|
],
|
||||||
"height": 103,
|
"height": 103,
|
||||||
"ins": 3,
|
"ins": 3,
|
||||||
"maxfee": 49800,
|
"maxfee": 49800,
|
||||||
"maxfeerate": 300,
|
"maxfeerate": 300,
|
||||||
"maxtxsize": 248,
|
"maxtxsize": 248,
|
||||||
"medianfee": 3760,
|
"medianfee": 3760,
|
||||||
"medianfeerate": 20,
|
|
||||||
"mediantime": 1525107243,
|
"mediantime": 1525107243,
|
||||||
"mediantxsize": 248,
|
"mediantxsize": 248,
|
||||||
"minfee": 3320,
|
"minfee": 3320,
|
||||||
|
|
|
@ -27,7 +27,7 @@ class GetblockstatsTest(BitcoinTestFramework):
|
||||||
'maxfee',
|
'maxfee',
|
||||||
'maxfeerate',
|
'maxfeerate',
|
||||||
'medianfee',
|
'medianfee',
|
||||||
'medianfeerate',
|
'feerate_percentiles',
|
||||||
'minfee',
|
'minfee',
|
||||||
'minfeerate',
|
'minfeerate',
|
||||||
'totalfee',
|
'totalfee',
|
||||||
|
|
Loading…
Add table
Reference in a new issue