Skip to content

Commit

Permalink
Add value tracking stats
Browse files Browse the repository at this point in the history
Tracks total value of many_to_one outputs.
Tracks total value of different kinds of SegWit outputs spent.
Tracks total value of native SegWit outputs created.
  • Loading branch information
Marcin Jachymiak committed Aug 14, 2018
1 parent 7a2aa5f commit 8968f34
Showing 1 changed file with 34 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1755,6 +1755,13 @@ static UniValue getblockstats(const JSONRPCRequest& request)
" \"dust_bins\": xxxxx, (numeric_array) The total number of outputs that are dust at several fee-rates\n"
" \"mto_consolidations\": xxxxx, (numeric) The total number of transactions with at least 3 inputs and exactly 1 output\n"
" \"mto_output_count\": xxxxx, (numeric) The total number of outputs spent in all mto_consolidation transactions\n"
" \"mto_total_value\": xxxxx, (numeric) The sum of values of all outputs from mto_consolidation transactions\n"
" \"value_of_nested_p2wpkh_outputs_spent\": xxxxx, (numeric) The total value of spent nested P2WPKH outputs\n"
" \"value_of_nested_p2wsh_outputs_spent\": xxxxx, (numeric) The total value of spent nested P2WSH outputs\n"
" \"value_of_native_p2wpkh_outputs_spent\": xxxxx, (numeric) The total value of spent native P2WPKH outputs\n"
" \"value_of_native_p2wsh_outputs_spent\": xxxxx, (numeric) The total value of spent native P2WSH outputs\n"
" \"value_of_native_p2wpkh_outputs_created\": xxxxx, (numeric) The total value of new native P2WPKH outputs\n"
" \"value_of_native_p2wsh_outputs_created\": xxxxx, (numeric) The total value of new native P2WSH outputs\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("getblockstats", "1000 '[\"minfeerate\",\"avgfeerate\"]'")
Expand Down Expand Up @@ -1800,7 +1807,6 @@ static UniValue getblockstats(const JSONRPCRequest& request)
}

const CBlock block = GetBlockChecked(pindex);

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_medianfee = do_all || stats.count("medianfee") != 0;
Expand Down Expand Up @@ -1836,6 +1842,12 @@ static UniValue getblockstats(const JSONRPCRequest& request)
int64_t native_p2wsh_outputs_spent = 0;
int64_t nested_p2wpkh_outputs_spent = 0;
int64_t nested_p2wsh_outputs_spent = 0;
int64_t value_of_native_p2wpkh_outputs_created = 0;
int64_t value_of_native_p2wsh_outputs_created = 0;
int64_t value_of_native_p2wpkh_outputs_spent = 0;
int64_t value_of_native_p2wsh_outputs_spent = 0;
int64_t value_of_nested_p2wpkh_outputs_spent = 0;
int64_t value_of_nested_p2wsh_outputs_spent = 0;
int64_t txs_spending_nested_p2wpkh_outputs = 0;
int64_t txs_spending_nested_p2wsh_outputs = 0;
int64_t txs_spending_native_p2wpkh_outputs = 0;
Expand All @@ -1853,6 +1865,7 @@ static UniValue getblockstats(const JSONRPCRequest& request)
std::vector<int64_t> cons_in_count;
int64_t many_to_one_consolidating_txs = 0;
int64_t many_to_one_consolidated_outputs = 0;
CAmount many_to_one_total_value = 0;

// Batch ranges = [(1), (2), (3-4), (5-9), (10-49), (50-99), (100+)]
constexpr int NUM_OUTCOUNT_BINS = 7;
Expand Down Expand Up @@ -1895,9 +1908,11 @@ static UniValue getblockstats(const JSONRPCRequest& request)
if (scriptPubKey.IsPayToWitnessScriptHash()) {
++new_p2wsh_outputs;
creates_p2wsh_output = true;
value_of_native_p2wsh_outputs_created += out.nValue;
} else if (scriptPubKey.IsNativePayToWitnessPubKeyHash()) {
++new_p2wpkh_outputs;
creates_p2wpkh_output = true;
value_of_native_p2wpkh_outputs_created += out.nValue;
}

tx_total_out += out.nValue;
Expand Down Expand Up @@ -1933,10 +1948,12 @@ static UniValue getblockstats(const JSONRPCRequest& request)
outputs_consolidated += tx->vin.size();
}

bool tx_is_many_to_one = false;
// Look for transactions with high number of inputs and low outputs
if ((tx->vin.size() >= CONSOLIDATION_THRESHOLD) && tx->vout.size() == 1) {
++many_to_one_consolidating_txs;
many_to_one_consolidated_outputs += tx->vin.size();
tx_is_many_to_one = true;
}

int64_t tx_size = 0;
Expand Down Expand Up @@ -1993,15 +2010,19 @@ static UniValue getblockstats(const JSONRPCRequest& request)
if (in.SpendsNestedPayToWitnessPubKeyHashOutput(scriptPubKey)) {
spends_nested_p2wpkh_output = true;
++nested_p2wpkh_outputs_spent;
value_of_nested_p2wpkh_outputs_spent += prevoutput.nValue;
} else if (in.SpendsNestedPayToWitnessScriptHashOutput(scriptPubKey)) {
spends_nested_p2wsh_output = true;
++nested_p2wsh_outputs_spent;
value_of_nested_p2wsh_outputs_spent += prevoutput.nValue;
} else if (in.SpendsNativePayToWitnessPubKeyHashOutput(scriptPubKey)) {
spends_native_p2wpkh_output = true;
++native_p2wpkh_outputs_spent;
value_of_native_p2wpkh_outputs_spent += prevoutput.nValue;
} else if (in.SpendsNativePayToWitnessScriptHashOutput(scriptPubKey)) {
spends_native_p2wsh_output = true;
++native_p2wsh_outputs_spent;
value_of_native_p2wsh_outputs_spent += prevoutput.nValue;
}

tx_total_in += prevoutput.nValue;
Expand Down Expand Up @@ -2046,6 +2067,10 @@ static UniValue getblockstats(const JSONRPCRequest& request)
}
maxfeerate = std::max(maxfeerate, feerate);
minfeerate = std::min(minfeerate, feerate);

if (tx_is_many_to_one) {
many_to_one_total_value += tx_total_out;
}
}
}

Expand Down Expand Up @@ -2123,6 +2148,14 @@ static UniValue getblockstats(const JSONRPCRequest& request)

ret_all.pushKV("mto_consolidations", many_to_one_consolidating_txs);
ret_all.pushKV("mto_output_count", many_to_one_consolidated_outputs);
ret_all.pushKV("mto_total_value", many_to_one_total_value);

ret_all.pushKV("value_of_nested_p2wpkh_outputs_spent", value_of_nested_p2wpkh_outputs_spent);
ret_all.pushKV("value_of_nested_p2wsh_outputs_spent", value_of_nested_p2wsh_outputs_spent);
ret_all.pushKV("value_of_native_p2wpkh_outputs_spent", value_of_native_p2wpkh_outputs_spent);
ret_all.pushKV("value_of_native_p2wsh_outputs_spent", value_of_native_p2wsh_outputs_spent);
ret_all.pushKV("value_of_native_p2wpkh_outputs_created", value_of_native_p2wpkh_outputs_created);
ret_all.pushKV("value_of_native_p2wsh_outputs_created", value_of_native_p2wsh_outputs_created);

if (do_all) {
return ret_all;
Expand Down

0 comments on commit 8968f34

Please sign in to comment.