#260 Add votes function to database_api and wallet_api

This commit is contained in:
Vlad Dobromyslov 2022-02-04 09:15:34 +03:00
parent 5247f76fc2
commit 889265406a
5 changed files with 256 additions and 4 deletions

View file

@ -175,6 +175,23 @@ public:
// Votes
vector<variant> lookup_vote_ids(const vector<vote_id_type> &votes) const;
vector<vote_id_type> get_votes_ids(const string &account_name_or_id) const;
template<typename IndexType, typename Tag>
vector<variant> get_votes_objects(const vector<vote_id_type> &votes, unsigned int variant_max_depth = 1) const
{
static_assert( std::is_base_of<index,IndexType>::value, "Type must be an index type" );
vector<variant> result;
const auto &idx = _db.get_index_type<IndexType>().indices().template get<Tag>();
for (auto id : votes) {
auto itr = idx.find(id);
if (itr != idx.end())
result.emplace_back(variant(*itr,variant_max_depth));
}
return result;
}
votes_info get_votes(const string &account_name_or_id) const;
vector<account_object> get_voters_by_id(const vote_id_type &vote_id) const;
// Authority / validation
std::string get_transaction_hex(const signed_transaction &trx) const;
@ -234,6 +251,9 @@ public:
vector<offer_history_object> get_offer_history_by_item(const offer_history_id_type lower_id, const nft_id_type item, uint32_t limit) const;
vector<offer_history_object> get_offer_history_by_bidder(const offer_history_id_type lower_id, const account_id_type bidder_account_id, uint32_t limit) const;
// Account Role
vector<account_role_object> get_account_roles_by_owner(account_id_type owner) const;
uint32_t api_limit_get_lower_bound_symbol = 100;
uint32_t api_limit_get_limit_orders = 300;
uint32_t api_limit_get_limit_orders_by_account = 101;
@ -245,9 +265,6 @@ public:
uint32_t api_limit_get_trade_history = 100;
uint32_t api_limit_get_trade_history_by_sequence = 100;
// Account Role
vector<account_role_object> get_account_roles_by_owner(account_id_type owner) const;
//private:
const account_object *get_account_from_string(const std::string &name_or_id,
bool throw_if_not_found = true) const;
@ -1885,6 +1902,18 @@ vector<variant> database_api::lookup_vote_ids(const vector<vote_id_type> &votes)
return my->lookup_vote_ids(votes);
}
vector<vote_id_type> database_api::get_votes_ids(const string &account_name_or_id) const {
return my->get_votes_ids(account_name_or_id);
}
votes_info database_api::get_votes(const string &account_name_or_id) const {
return my->get_votes(account_name_or_id);
}
vector<account_object> database_api::get_voters_by_id(const vote_id_type &vote_id) const {
return my->get_voters_by_id(vote_id);
}
vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &votes) const {
FC_ASSERT(votes.size() < 1000, "Only 1000 votes can be queried at a time");
@ -1946,6 +1975,78 @@ vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &v
return result;
}
vector<vote_id_type> database_api_impl::get_votes_ids(const string &account_name_or_id) const {
vector<vote_id_type> result;
const account_object *account = get_account_from_string(account_name_or_id);
//! Iterate throug votes and fill vector
for( const auto& vote : account->options.votes )
{
result.emplace_back(vote);
}
return result;
}
votes_info database_api_impl::get_votes(const string &account_name_or_id) const {
votes_info result;
const auto& votes_ids = get_votes_ids(account_name_or_id);
const auto& committee_ids = get_votes_objects<committee_member_index, by_vote_id>(votes_ids);
const auto& witness_ids = get_votes_objects<witness_index, by_vote_id>(votes_ids);
const auto& for_worker_ids = get_votes_objects<worker_index, by_vote_for>(votes_ids);
const auto& against_worker_ids = get_votes_objects<worker_index, by_vote_against>(votes_ids);
const auto& son_ids = get_votes_objects<son_index, by_vote_id>(votes_ids, 5);
//! Fill votes info
result.votes_for_committee_members.reserve(committee_ids.size());
for(const auto& committee : committee_ids)
{
const auto& committee_obj = committee.as<committee_member_object>(2);
result.votes_for_committee_members.emplace_back( votes_info_object<committee_member_id_type>{ committee_obj.vote_id, committee_obj.id.instance() } );
}
result.votes_for_witnesses.reserve(witness_ids.size());
for(const auto& witness : witness_ids)
{
const auto& witness_obj = witness.as<witness_object>(2);
result.votes_for_witnesses.emplace_back( votes_info_object<witness_id_type>{ witness_obj.vote_id, witness_obj.id.instance() } );
}
result.votes_for_workers.reserve(for_worker_ids.size());
for(const auto& for_worker : for_worker_ids)
{
const auto& for_worker_obj = for_worker.as<worker_object>(2);
result.votes_for_workers.emplace_back( votes_info_object<worker_id_type>{ for_worker_obj.vote_for, for_worker_obj.id.instance() } );
}
result.votes_against_workers.reserve(against_worker_ids.size());
for(const auto& against_worker : against_worker_ids)
{
const auto& against_worker_obj = against_worker.as<worker_object>(2);
result.votes_against_workers.emplace_back( votes_info_object<worker_id_type>{ against_worker_obj.vote_against, against_worker_obj.id.instance() } );
}
result.votes_for_sons.reserve(son_ids.size());
for(const auto& son : son_ids)
{
const auto& son_obj = son.as<son_object>(6);
result.votes_for_sons.emplace_back( votes_info_object<son_id_type>{ son_obj.vote_id, son_obj.id.instance() } );
}
return result;
}
vector<account_object> database_api_impl::get_voters_by_id(const vote_id_type &vote_id) const {
vector<account_object> result;
//! We search all accounts that have voted for this vote_id
const auto& account_index = _db.get_index_type<graphene::chain::account_index>().indices().get<by_id>();
for( const auto& account: account_index )
{
if(account.options.votes.count(vote_id) != 0)
result.emplace_back(account);
}
return result;
}
//////////////////////////////////////////////////////////////////////
// //
// Authority / validation //

View file

@ -56,6 +56,7 @@
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/nft_object.hpp>
#include <graphene/chain/offer_object.hpp>
#include <graphene/chain/votes_info.hpp>
#include <graphene/market_history/market_history_plugin.hpp>
@ -721,6 +722,36 @@ public:
*/
vector<variant> lookup_vote_ids(const vector<vote_id_type> &votes) const;
/**
* @brief Get a list that ID votes for
* @param account_name_or_id ID or name of the account to get votes for
* @return The list of vote_id_type ID votes for
*
*/
vector<vote_id_type> get_votes_ids(const string &account_name_or_id) const;
/**
* @brief Given a set of votes, return the objects ID votes for
*
* This will be a mixture of committee_member_object, witness_objects, and worker_objects
*
* The results will be in the same order as the votes. Null will be returned for
* any vote ids that are not found.
*
* @param account_name_or_id ID or name of the account to get votes for
* @return The set of votes ID votes for
*
*/
votes_info get_votes(const string &account_name_or_id) const;
/**
* @brief Get a list of accounts that votes for vote_id
* @param vote_id We search accounts that vote for this ID
* @return The accounts that votes for provided ID
*
*/
vector<account_object> get_voters_by_id(const vote_id_type &vote_id) const;
////////////////////////////
// Authority / validation //
////////////////////////////
@ -1062,8 +1093,12 @@ FC_API(graphene::app::database_api,
// workers
(get_workers_by_account)
// Votes
(lookup_vote_ids)
(get_votes_ids)
(get_votes)
(get_voters_by_id)
// Authority / validation
(get_transaction_hex)

View file

@ -0,0 +1,48 @@
#pragma once
#include <graphene/chain/protocol/vote.hpp>
namespace graphene { namespace chain {
/**
* @class votes_info_object
* @tparam IdType id type of the object
* @ingroup object
*/
template<typename IdType>
struct votes_info_object {
votes_info_object() = default;
votes_info_object(const vote_id_type& vote_id_, uint64_t id_)
: vote_id{vote_id_}
, id{id_}
{}
vote_id_type vote_id;
IdType id;
};
/**
* @class votes_info
* @brief tracks information about a votes info
* @ingroup object
*/
struct votes_info {
vector< votes_info_object<committee_member_id_type> > votes_for_committee_members;
vector< votes_info_object<witness_id_type> > votes_for_witnesses;
vector< votes_info_object<worker_id_type> > votes_for_workers;
vector< votes_info_object<worker_id_type> > votes_against_workers;
vector< votes_info_object<son_id_type> > votes_for_sons;
};
} } // graphene::chain
FC_REFLECT_TEMPLATE( (typename IdType), graphene::chain::votes_info_object<IdType>,
(vote_id)
(id) )
FC_REFLECT( graphene::chain::votes_info,
(votes_for_committee_members)
(votes_for_witnesses)
(votes_for_workers)
(votes_against_workers)
(votes_for_sons) )

View file

@ -2487,9 +2487,32 @@ class wallet_api
bool broadcast = false,
bool to_temp = false );
std::map<string,std::function<string(fc::variant,const fc::variants&)>> get_result_formatters() const;
/**
* @brief Get a list of vote_id_type that ID votes for
* @param account_name_or_id ID or name of the account to get votes for
* @return The list of vote_id_type ID votes for
*
*/
vector<vote_id_type> get_votes_ids(const string &account_name_or_id) const;
/**
* @brief Return the objects account_name_or_id votes for
* @param account_name_or_id ID or name of the account to get votes for
* @return The votes_info account_name_or_id votes for
*
*/
votes_info get_votes(const string &account_name_or_id) const;
/**
* @brief Get a list of accounts that votes for vote_id
* @param vote_id We search accounts that vote for this ID
* @return The accounts that votes for provided ID
*
*/
vector<account_object> get_voters_by_id(const vote_id_type &vote_id) const;
fc::signal<void(bool)> lock_changed;
std::shared_ptr<detail::wallet_api_impl> my;
void encrypt_keys();
@ -2795,4 +2818,7 @@ FC_API( graphene::wallet::wallet_api,
(get_custom_account_authorities_by_permission_id)
(get_custom_account_authorities_by_permission_name)
(get_active_custom_account_authorities_by_operation)
(get_votes_ids)
(get_votes)
(get_voters_by_id)
)

View file

@ -4082,6 +4082,33 @@ public:
return it->second;
}
vector<vote_id_type> get_votes_ids(const string &account_name_or_id) const
{
try
{
return _remote_db->get_votes_ids(account_name_or_id);
}
FC_CAPTURE_AND_RETHROW( (account_name_or_id) )
}
votes_info get_votes(const string &account_name_or_id) const
{
try
{
return _remote_db->get_votes(account_name_or_id);
}
FC_CAPTURE_AND_RETHROW( (account_name_or_id) )
}
vector<account_object> get_voters_by_id(const vote_id_type &vote_id) const
{
try
{
return _remote_db->get_voters_by_id(vote_id);
}
FC_CAPTURE_AND_RETHROW( (vote_id) )
}
string _wallet_filename;
wallet_data _wallet;
@ -7583,6 +7610,21 @@ std::vector<matched_bet_object> wallet_api::get_all_matched_bets_for_bettor(acco
return( my->_remote_bookie->get_all_matched_bets_for_bettor(bettor_id, start, limit) );
}
vector<vote_id_type> wallet_api::get_votes_ids(const string &account_name_or_id) const
{
return my->get_votes_ids(account_name_or_id);
}
votes_info wallet_api::get_votes(const string &account_name_or_id) const
{
return my->get_votes(account_name_or_id);
}
vector<account_object> wallet_api::get_voters_by_id(const vote_id_type &vote_id) const
{
return my->get_voters_by_id(vote_id);
}
// default ctor necessary for FC_REFLECT
signed_block_with_info::signed_block_with_info( const signed_block& block )
: signed_block( block )