diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 928ad04f6bf53ee47b577f5e73248a21fe481cfe..9eb0efbd7bdebcbd9b53c73bbf499448c78c089e 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -403,11 +403,27 @@ static float64_t to_softfloat64( double d ) { return *reinterpret_cast(&d); } +static fc::variant get_global_row( const database& db, const abi_def& abi, const abi_serializer& abis ) { + const auto table_type = get_table_type(abi, N(global)); + EOS_ASSERT(table_type == read_only::KEYi64, chain::contract_table_query_exception, "Invalid table type ${type} for table global", ("type",table_type)); + + const auto* const table_id = db.find(boost::make_tuple(N(eosio), N(eosio), N(global))); + EOS_ASSERT(table_id, chain::contract_table_query_exception, "Missing table global"); + + const auto& kv_index = db.get_index(); + const auto it = kv_index.find(boost::make_tuple(table_id->id, N(global))); + EOS_ASSERT(it != kv_index.end(), chain::contract_table_query_exception, "Missing row in table global"); + + vector data; + read_only::copy_inline_row(*it, data); + return abis.binary_to_variant(abis.get_table_type(N(global)), data); +} + read_only::get_producers_result read_only::get_producers( const read_only::get_producers_params& p ) const { const abi_def abi = get_abi(db, N(eosio)); const auto table_type = get_table_type(abi, N(producers)); const abi_serializer abis{ abi }; - EOS_ASSERT(table_type == KEYi64, chain::contract_table_query_exception, "Invalid table type ${type}", ("type",table_type)); + EOS_ASSERT(table_type == KEYi64, chain::contract_table_query_exception, "Invalid table type ${type} for table producers", ("type",table_type)); const auto& d = db.db(); const auto lower = name{p.lower_bound}; @@ -448,6 +464,7 @@ read_only::get_producers_result read_only::get_producers( const read_only::get_p result.rows.emplace_back(fc::variant(data)); } + result.total_producer_vote_weight = get_global_row(d, abi, abis)["total_producer_vote_weight"].as_double(); return result; } diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 835ce9ae5a96183dcf06255daca4620a45b8024a..9247bbea1240a54f8e87bf34ae47e0f13243139a 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -216,6 +216,7 @@ public: struct get_producers_result { vector rows; ///< one row per item, either encoded as hex string or JSON object + double total_producer_vote_weight; string more; ///< fill lower_bound with this value to fetch more rows }; @@ -397,7 +398,7 @@ FC_REFLECT( eosio::chain_apis::read_only::get_currency_stats_params, (code)(symb FC_REFLECT( eosio::chain_apis::read_only::get_currency_stats_result, (supply)(max_supply)(issuer)); FC_REFLECT( eosio::chain_apis::read_only::get_producers_params, (json)(lower_bound)(limit) ) -FC_REFLECT( eosio::chain_apis::read_only::get_producers_result, (rows)(more) ); +FC_REFLECT( eosio::chain_apis::read_only::get_producers_result, (rows)(total_producer_vote_weight)(more) ); FC_REFLECT( eosio::chain_apis::read_only::get_account_results, (account_name)(privileged)(last_code_update)(created)(ram_quota)(net_weight)(cpu_weight)(net_limit)(cpu_limit)(ram_usage)(permissions)(total_resources)(delegated_bandwidth)(voter_info) ) FC_REFLECT( eosio::chain_apis::read_only::get_code_results, (account_name)(code_hash)(wast)(abi) ) diff --git a/programs/cleos/main.cpp b/programs/cleos/main.cpp index fc2d80505ffba69221b21c96836aba72e886a478..80b86ea8b010d9ac6d3eef96eb3832b23700c576 100644 --- a/programs/cleos/main.cpp +++ b/programs/cleos/main.cpp @@ -1031,13 +1031,16 @@ struct list_producers_subcommand { std::cout << "No producers found" << std::endl; return; } - printf("%-13s %-54s %-59s %s\n", "Producer", "Producer key", "Url", "Total votes"); + auto weight = result.total_producer_vote_weight; + if ( !weight ) + weight = 1; + printf("%-13s %-54s %-59s %s\n", "Producer", "Producer key", "Url", "Scaled votes"); for ( auto& row : result.rows ) - printf("%-13.13s %-54.54s %-59.59s %040f\n", + printf("%-13.13s %-54.54s %-59.59s %1.4f\n", row["owner"].as_string().c_str(), row["producer_key"].as_string().c_str(), row["url"].as_string().c_str(), - row["total_votes"].as_double()); + row["total_votes"].as_double() / weight); if ( !result.more.empty() ) std::cout << "-L " << result.more << " for more" << std::endl; });