28
28
#include < sync.h>
29
29
#include < txdb.h>
30
30
#include < txmempool.h>
31
+ #include < undo.h>
31
32
#include < util/strencodings.h>
32
33
#include < util/system.h>
33
34
#include < util/validation.h>
@@ -822,6 +823,20 @@ static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
822
823
return block;
823
824
}
824
825
826
+ static CBlockUndo GetUndoChecked (const CBlockIndex* pblockindex)
827
+ {
828
+ CBlockUndo blockUndo;
829
+ if (IsBlockPruned (pblockindex)) {
830
+ throw JSONRPCError (RPC_MISC_ERROR, " Undo data not available (pruned data)" );
831
+ }
832
+
833
+ if (!UndoReadFromDisk (blockUndo, pblockindex)) {
834
+ throw JSONRPCError (RPC_MISC_ERROR, " Can't read undo data from disk" );
835
+ }
836
+
837
+ return blockUndo;
838
+ }
839
+
825
840
static UniValue getblock (const JSONRPCRequest& request)
826
841
{
827
842
if (request.fHelp || request.params .size () < 1 || request.params .size () > 2 )
@@ -1783,8 +1798,7 @@ static UniValue getblockstats(const JSONRPCRequest& request)
1783
1798
{
1784
1799
const RPCHelpMan help{" getblockstats" ,
1785
1800
" \n Compute per block statistics for a given window. All amounts are in satoshis.\n "
1786
- " It won't work for some heights with pruning.\n "
1787
- " It won't work without -txindex for utxo_size_inc, *fee or *feerate stats.\n " ,
1801
+ " It won't work for some heights with pruning.\n " ,
1788
1802
{
1789
1803
{" hash_or_height" , RPCArg::Type::NUM, RPCArg::Optional::NO, " The block hash or height of the target block" , " " , {" " , " string or numeric" }},
1790
1804
{" stats" , RPCArg::Type::ARR, /* default */ " all values" , " Values to plot (see result below)" ,
@@ -1879,6 +1893,7 @@ static UniValue getblockstats(const JSONRPCRequest& request)
1879
1893
}
1880
1894
1881
1895
const CBlock block = GetBlockChecked (pindex);
1896
+ const CBlockUndo blockUndo = GetUndoChecked (pindex);
1882
1897
1883
1898
const bool do_all = stats.size () == 0 ; // Calculate everything if nothing selected (default)
1884
1899
const bool do_mediantxsize = do_all || stats.count (" mediantxsize" ) != 0 ;
@@ -1892,10 +1907,6 @@ static UniValue getblockstats(const JSONRPCRequest& request)
1892
1907
const bool do_calculate_weight = do_all || SetHasKeys (stats, " total_weight" , " avgfeerate" , " swtotal_weight" , " avgfeerate" , " feerate_percentiles" , " minfeerate" , " maxfeerate" );
1893
1908
const bool do_calculate_sw = do_all || SetHasKeys (stats, " swtxs" , " swtotal_size" , " swtotal_weight" );
1894
1909
1895
- if (loop_inputs && !g_txindex) {
1896
- throw JSONRPCError (RPC_INVALID_PARAMETER, " One or more of the selected stats requires -txindex enabled" );
1897
- }
1898
-
1899
1910
CAmount maxfee = 0 ;
1900
1911
CAmount maxfeerate = 0 ;
1901
1912
CAmount minfee = MAX_MONEY;
@@ -1916,7 +1927,8 @@ static UniValue getblockstats(const JSONRPCRequest& request)
1916
1927
std::vector<std::pair<CAmount, int64_t >> feerate_array;
1917
1928
std::vector<int64_t > txsize_array;
1918
1929
1919
- for (const auto & tx : block.vtx ) {
1930
+ for (size_t i = 0 ; i < block.vtx .size (); ++i) {
1931
+ const auto & tx = block.vtx .at (i);
1920
1932
outputs += tx->vout .size ();
1921
1933
1922
1934
CAmount tx_total_out = 0 ;
@@ -1960,14 +1972,9 @@ static UniValue getblockstats(const JSONRPCRequest& request)
1960
1972
1961
1973
if (loop_inputs) {
1962
1974
CAmount tx_total_in = 0 ;
1963
- for (const CTxIn& in : tx->vin ) {
1964
- CTransactionRef tx_in;
1965
- uint256 hashBlock;
1966
- if (!GetTransaction (in.prevout .hash , tx_in, Params ().GetConsensus (), hashBlock)) {
1967
- throw JSONRPCError (RPC_INTERNAL_ERROR, std::string (" Unexpected internal error (tx index seems corrupt)" ));
1968
- }
1969
-
1970
- CTxOut prevoutput = tx_in->vout [in.prevout .n ];
1975
+ const auto & txundo = blockUndo.vtxundo .at (i - 1 );
1976
+ for (const Coin& coin: txundo.vprevout ) {
1977
+ const CTxOut& prevoutput = coin.out ;
1971
1978
1972
1979
tx_total_in += prevoutput.nValue ;
1973
1980
utxo_size_inc -= GetSerializeSize (prevoutput, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD;
0 commit comments