message: getblockstats: Consider ct_fee as tx fee if available
  Otherwise fall back to subtraction (mainly basecoin-to-basecoin) or skipping.
diff: @@ -2076,10 +2076,6 @@ static UniValue getblockstats(const JSONRPCRequest& request)
  if (tx->IsCoinStake()) {
  continue;
  }
  - if (tx->vin[0].IsAnonInput()) {
  - // Can't really do much with a ringCT transaction
  - continue;
  - }
  inputs += tx->vin.size(); // Don't count coinbase's fake input
  total_out += tx_total_out; // Don't count coinbase reward
  @@ -2110,9 +2106,17 @@ static UniValue getblockstats(const JSONRPCRequest& request)
  if (loop_inputs) {
  + CAmount txfee;
  + if (tx->vin[0].IsAnonInput()) {
  + if (!tx->GetCTFee(txfee)) {
  + // Can't really do much with a ringCT transaction with no fee
  + continue;
  + }
  + } else {
  if (!g_txindex) {
  throw JSONRPCError(RPC_INVALID_PARAMETER, "One or more of the selected stats requires -txindex enabled");
  }
  + // Total up the utxo_size_inc even if we have a ct_fee
  CAmount tx_total_in = 0;
  for (const CTxIn& in : tx->vin) {
  if (!in.IsZerocoinSpend()) {
  @@ -2132,12 +2136,16 @@ static UniValue getblockstats(const JSONRPCRequest& request)
  tx_total_in += in.GetZerocoinSpent();
  }
  }
  -
  - CAmount txfee = tx_total_in - tx_total_out;
  + // Prefer the ct_fee over the difference
  + if (!tx->GetCTFee(txfee)) {
  + txfee = tx_total_in - tx_total_out;
  if (tx_total_in < tx_total_out) {
  // RingCT with hidden inputs, can't count it
  continue;
  }
  + }
  + }
  +
  assert(MoneyRange(txfee));
  if (do_medianfee) {
  fee_array.push_back(txfee);
  