Merge remote-tracking branch 'glu/develop' into dapp-support
This commit is contained in:
commit
659d135b9b
15 changed files with 920 additions and 68 deletions
14
.gitmodules
vendored
14
.gitmodules
vendored
|
|
@ -1,9 +1,9 @@
|
|||
[submodule "docs"]
|
||||
path = docs
|
||||
url = https://github.com/bitshares/bitshares-core.wiki.git
|
||||
ignore = dirty
|
||||
path = docs
|
||||
url = https://github.com/bitshares/bitshares-core.wiki.git
|
||||
ignore = dirty
|
||||
[submodule "libraries/fc"]
|
||||
path = libraries/fc
|
||||
url = https://github.com/nathanhourt/peerplays-fc
|
||||
branch = latest-fc
|
||||
ignore = dirty
|
||||
path = libraries/fc
|
||||
url = https://gitlab.com/PBSA/tools-libs/peerplays-fc.git
|
||||
branch = dapp-support
|
||||
ignore = dirty
|
||||
|
|
|
|||
2
docs
2
docs
|
|
@ -1 +1 @@
|
|||
Subproject commit 8df8f66389853df73ab8f6dd73981be2a6957df8
|
||||
Subproject commit 1e924950c2f92b166c34ceb294e8b8c4997a6c4e
|
||||
|
|
@ -55,6 +55,30 @@ template class fc::api<graphene::app::database_api>;
|
|||
|
||||
namespace graphene { namespace app {
|
||||
|
||||
template<class T>
|
||||
optional<T> maybe_id( const string& name_or_id )
|
||||
{
|
||||
if( std::isdigit( name_or_id.front() ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
return fc::variant(name_or_id, 1).as<T>(1);
|
||||
}
|
||||
catch (const fc::exception&)
|
||||
{ // not an ID
|
||||
}
|
||||
}
|
||||
return optional<T>();
|
||||
}
|
||||
|
||||
std::string object_id_to_string(object_id_type id)
|
||||
{
|
||||
std::string object_id = fc::to_string(id.space())
|
||||
+ "." + fc::to_string(id.type())
|
||||
+ "." + fc::to_string(id.instance());
|
||||
return object_id;
|
||||
}
|
||||
|
||||
class database_api_impl : public std::enable_shared_from_this<database_api_impl> {
|
||||
public:
|
||||
database_api_impl(graphene::chain::database &db);
|
||||
|
|
@ -149,18 +173,22 @@ public:
|
|||
|
||||
// Witnesses
|
||||
vector<optional<witness_object>> get_witnesses(const vector<witness_id_type> &witness_ids) const;
|
||||
fc::optional<witness_object> get_witness_by_account_id(account_id_type account) const;
|
||||
fc::optional<witness_object> get_witness_by_account(const std::string account_id_or_name) const;
|
||||
map<string, witness_id_type> lookup_witness_accounts(const string &lower_bound_name, uint32_t limit) const;
|
||||
uint64_t get_witness_count() const;
|
||||
|
||||
// Committee members
|
||||
vector<optional<committee_member_object>> get_committee_members(const vector<committee_member_id_type> &committee_member_ids) const;
|
||||
fc::optional<committee_member_object> get_committee_member_by_account_id(account_id_type account) const;
|
||||
fc::optional<committee_member_object> get_committee_member_by_account(const std::string account_id_or_name) const;
|
||||
map<string, committee_member_id_type> lookup_committee_member_accounts(const string &lower_bound_name, uint32_t limit) const;
|
||||
uint64_t get_committee_member_count() const;
|
||||
|
||||
// SON members
|
||||
vector<optional<son_object>> get_sons(const vector<son_id_type> &son_ids) const;
|
||||
fc::optional<son_object> get_son_by_account(account_id_type account) const;
|
||||
fc::optional<son_object> get_son_by_account_id(account_id_type account) const;
|
||||
fc::optional<son_object> get_son_by_account(const std::string account_id_or_name) const;
|
||||
map<string, son_id_type> lookup_son_accounts(const string &lower_bound_name, uint32_t limit) const;
|
||||
uint64_t get_son_count() const;
|
||||
|
||||
|
|
@ -176,8 +204,33 @@ public:
|
|||
fc::optional<sidechain_address_object> get_sidechain_address_by_account_and_sidechain(account_id_type account, sidechain_type sidechain) const;
|
||||
uint64_t get_sidechain_addresses_count() const;
|
||||
|
||||
// Workers
|
||||
vector<optional<worker_object>> get_workers(const vector<worker_id_type> &witness_ids) const;
|
||||
vector<worker_object> get_workers_by_account_id(account_id_type account) const;
|
||||
vector<worker_object> get_workers_by_account(const std::string account_id_or_name) const;
|
||||
map<string, worker_id_type> lookup_worker_accounts(const string &lower_bound_name, uint32_t limit) const;
|
||||
uint64_t get_worker_count() const;
|
||||
|
||||
// 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;
|
||||
voters_info get_voters(const string &account_name_or_id) const;
|
||||
|
||||
// Authority / validation
|
||||
std::string get_transaction_hex(const signed_transaction &trx) const;
|
||||
|
|
@ -237,6 +290,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,12 +301,11 @@ public:
|
|||
uint32_t api_limit_lookup_accounts = 1000;
|
||||
uint32_t api_limit_lookup_witness_accounts = 1000;
|
||||
uint32_t api_limit_lookup_committee_member_accounts = 1000;
|
||||
uint32_t api_limit_lookup_son_accounts = 1000;
|
||||
uint32_t api_limit_lookup_worker_accounts = 1000;
|
||||
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;
|
||||
|
|
@ -1555,20 +1610,6 @@ vector<optional<witness_object>> database_api::get_witnesses(const vector<witnes
|
|||
return my->get_witnesses(witness_ids);
|
||||
}
|
||||
|
||||
vector<worker_object> database_api::get_workers_by_account(const std::string account_id_or_name) const {
|
||||
const auto &idx = my->_db.get_index_type<worker_index>().indices().get<by_account>();
|
||||
const account_id_type account = my->get_account_from_string(account_id_or_name)->id;
|
||||
auto itr = idx.find(account);
|
||||
vector<worker_object> result;
|
||||
|
||||
if (itr != idx.end() && itr->worker_account == account) {
|
||||
result.emplace_back(*itr);
|
||||
++itr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<optional<witness_object>> database_api_impl::get_witnesses(const vector<witness_id_type> &witness_ids) const {
|
||||
vector<optional<witness_object>> result;
|
||||
result.reserve(witness_ids.size());
|
||||
|
|
@ -1581,17 +1622,25 @@ vector<optional<witness_object>> database_api_impl::get_witnesses(const vector<w
|
|||
return result;
|
||||
}
|
||||
|
||||
fc::optional<witness_object> database_api::get_witness_by_account_id(account_id_type account) const {
|
||||
return my->get_witness_by_account_id(account);
|
||||
}
|
||||
|
||||
fc::optional<witness_object> database_api_impl::get_witness_by_account_id(account_id_type account) const {
|
||||
const auto &idx = _db.get_index_type<witness_index>().indices().get<by_account>();
|
||||
auto itr = idx.find(account);
|
||||
if (itr != idx.end())
|
||||
return *itr;
|
||||
return {};
|
||||
}
|
||||
|
||||
fc::optional<witness_object> database_api::get_witness_by_account(const std::string account_id_or_name) const {
|
||||
return my->get_witness_by_account(account_id_or_name);
|
||||
}
|
||||
|
||||
fc::optional<witness_object> database_api_impl::get_witness_by_account(const std::string account_id_or_name) const {
|
||||
const auto &idx = _db.get_index_type<witness_index>().indices().get<by_account>();
|
||||
const account_id_type account = get_account_from_string(account_id_or_name)->id;
|
||||
auto itr = idx.find(account);
|
||||
if (itr != idx.end())
|
||||
return *itr;
|
||||
return {};
|
||||
return get_witness_by_account_id(account);
|
||||
}
|
||||
|
||||
map<string, witness_id_type> database_api::lookup_witness_accounts(const string &lower_bound_name, uint32_t limit) const {
|
||||
|
|
@ -1652,17 +1701,25 @@ vector<optional<committee_member_object>> database_api_impl::get_committee_membe
|
|||
return result;
|
||||
}
|
||||
|
||||
fc::optional<committee_member_object> database_api::get_committee_member_by_account_id(account_id_type account) const {
|
||||
return my->get_committee_member_by_account_id(account);
|
||||
}
|
||||
|
||||
fc::optional<committee_member_object> database_api_impl::get_committee_member_by_account_id(account_id_type account) const {
|
||||
const auto &idx = _db.get_index_type<committee_member_index>().indices().get<by_account>();
|
||||
auto itr = idx.find(account);
|
||||
if (itr != idx.end())
|
||||
return *itr;
|
||||
return {};
|
||||
}
|
||||
|
||||
fc::optional<committee_member_object> database_api::get_committee_member_by_account(const std::string account_id_or_name) const {
|
||||
return my->get_committee_member_by_account(account_id_or_name);
|
||||
}
|
||||
|
||||
fc::optional<committee_member_object> database_api_impl::get_committee_member_by_account(const std::string account_id_or_name) const {
|
||||
const auto &idx = _db.get_index_type<committee_member_index>().indices().get<by_account>();
|
||||
const account_id_type account = get_account_from_string(account_id_or_name)->id;
|
||||
auto itr = idx.find(account);
|
||||
if (itr != idx.end())
|
||||
return *itr;
|
||||
return {};
|
||||
return get_committee_member_by_account_id(account);
|
||||
}
|
||||
|
||||
map<string, committee_member_id_type> database_api::lookup_committee_member_accounts(const string &lower_bound_name, uint32_t limit) const {
|
||||
|
|
@ -1693,6 +1750,14 @@ map<string, committee_member_id_type> database_api_impl::lookup_committee_member
|
|||
return committee_members_by_account_name;
|
||||
}
|
||||
|
||||
uint64_t database_api::get_committee_member_count() const {
|
||||
return my->get_committee_member_count();
|
||||
}
|
||||
|
||||
uint64_t database_api_impl::get_committee_member_count() const {
|
||||
return _db.get_index_type<committee_member_index>().indices().size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// SON members //
|
||||
|
|
@ -1715,11 +1780,11 @@ vector<optional<son_object>> database_api_impl::get_sons(const vector<son_id_typ
|
|||
return result;
|
||||
}
|
||||
|
||||
fc::optional<son_object> database_api::get_son_by_account(account_id_type account) const {
|
||||
return my->get_son_by_account(account);
|
||||
fc::optional<son_object> database_api::get_son_by_account_id(account_id_type account) const {
|
||||
return my->get_son_by_account_id(account);
|
||||
}
|
||||
|
||||
fc::optional<son_object> database_api_impl::get_son_by_account(account_id_type account) const {
|
||||
fc::optional<son_object> database_api_impl::get_son_by_account_id(account_id_type account) const {
|
||||
const auto &idx = _db.get_index_type<son_index>().indices().get<by_account>();
|
||||
auto itr = idx.find(account);
|
||||
if (itr != idx.end())
|
||||
|
|
@ -1727,12 +1792,24 @@ fc::optional<son_object> database_api_impl::get_son_by_account(account_id_type a
|
|||
return {};
|
||||
}
|
||||
|
||||
fc::optional<son_object> database_api::get_son_by_account(const std::string account_id_or_name) const {
|
||||
return my->get_son_by_account(account_id_or_name);
|
||||
}
|
||||
|
||||
fc::optional<son_object> database_api_impl::get_son_by_account(const std::string account_id_or_name) const {
|
||||
const account_id_type account = get_account_from_string(account_id_or_name)->id;
|
||||
return get_son_by_account_id(account);
|
||||
}
|
||||
|
||||
map<string, son_id_type> database_api::lookup_son_accounts(const string &lower_bound_name, uint32_t limit) const {
|
||||
return my->lookup_son_accounts(lower_bound_name, limit);
|
||||
}
|
||||
|
||||
map<string, son_id_type> database_api_impl::lookup_son_accounts(const string &lower_bound_name, uint32_t limit) const {
|
||||
FC_ASSERT(limit <= 1000);
|
||||
FC_ASSERT(limit <= api_limit_lookup_son_accounts,
|
||||
"Number of querying accounts can not be greater than ${configured_limit}",
|
||||
("configured_limit", api_limit_lookup_son_accounts));
|
||||
|
||||
const auto &sons_by_id = _db.get_index_type<son_index>().indices().get<by_id>();
|
||||
|
||||
// we want to order sons by account name, but that name is in the account object
|
||||
|
|
@ -1878,6 +1955,91 @@ uint64_t database_api_impl::get_sidechain_addresses_count() const {
|
|||
return _db.get_index_type<sidechain_address_index>().indices().size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Workers //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
vector<optional<worker_object>> database_api::get_workers(const vector<worker_id_type> &worker_ids) const {
|
||||
return my->get_workers(worker_ids);
|
||||
}
|
||||
|
||||
vector<worker_object> database_api::get_workers_by_account_id(account_id_type account) const {
|
||||
return my->get_workers_by_account_id(account);
|
||||
}
|
||||
|
||||
vector<worker_object> database_api::get_workers_by_account(const std::string account_id_or_name) const {
|
||||
return my->get_workers_by_account(account_id_or_name);
|
||||
}
|
||||
|
||||
map<string, worker_id_type> database_api::lookup_worker_accounts(const string &lower_bound_name, uint32_t limit) const {
|
||||
return my->lookup_worker_accounts(lower_bound_name, limit);
|
||||
}
|
||||
|
||||
uint64_t database_api::get_worker_count() const {
|
||||
return my->get_worker_count();
|
||||
}
|
||||
|
||||
vector<optional<worker_object>> database_api_impl::get_workers(const vector<worker_id_type> &worker_ids) const {
|
||||
vector<optional<worker_object>> result;
|
||||
result.reserve(worker_ids.size());
|
||||
std::transform(worker_ids.begin(), worker_ids.end(), std::back_inserter(result),
|
||||
[this](worker_id_type id) -> optional<worker_object> {
|
||||
if (auto o = _db.find(id))
|
||||
return *o;
|
||||
return {};
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<worker_object> database_api_impl::get_workers_by_account_id(account_id_type account) const {
|
||||
const auto &idx = _db.get_index_type<worker_index>().indices().get<by_account>();
|
||||
auto itr = idx.find(account);
|
||||
vector<worker_object> result;
|
||||
|
||||
if (itr != idx.end() && itr->worker_account == account) {
|
||||
result.emplace_back(*itr);
|
||||
++itr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<worker_object> database_api_impl::get_workers_by_account(const std::string account_id_or_name) const {
|
||||
const account_id_type account = get_account_from_string(account_id_or_name)->id;
|
||||
return get_workers_by_account_id(account);
|
||||
}
|
||||
|
||||
map<string, worker_id_type> database_api_impl::lookup_worker_accounts(const string &lower_bound_name, uint32_t limit) const {
|
||||
FC_ASSERT(limit <= api_limit_lookup_worker_accounts,
|
||||
"Number of querying accounts can not be greater than ${configured_limit}",
|
||||
("configured_limit", api_limit_lookup_worker_accounts));
|
||||
|
||||
const auto &workers_by_id = _db.get_index_type<worker_index>().indices().get<by_id>();
|
||||
|
||||
// we want to order workers by account name, but that name is in the account object
|
||||
// so the worker_index doesn't have a quick way to access it.
|
||||
// get all the names and look them all up, sort them, then figure out what
|
||||
// records to return. This could be optimized, but we expect the
|
||||
// number of witnesses to be few and the frequency of calls to be rare
|
||||
std::map<std::string, worker_id_type> workers_by_account_name;
|
||||
for (const worker_object &worker : workers_by_id)
|
||||
if (auto account_iter = _db.find(worker.worker_account))
|
||||
if (account_iter->name >= lower_bound_name) // we can ignore anything below lower_bound_name
|
||||
workers_by_account_name.insert(std::make_pair(account_iter->name, worker.id));
|
||||
|
||||
auto end_iter = workers_by_account_name.begin();
|
||||
while (end_iter != workers_by_account_name.end() && limit--)
|
||||
++end_iter;
|
||||
workers_by_account_name.erase(end_iter, workers_by_account_name.end());
|
||||
return workers_by_account_name;
|
||||
}
|
||||
|
||||
uint64_t database_api_impl::get_worker_count() const {
|
||||
return _db.get_index_type<worker_index>().indices().size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Votes //
|
||||
|
|
@ -1888,6 +2050,22 @@ 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);
|
||||
}
|
||||
|
||||
voters_info database_api::get_voters(const string &account_name_or_id) const {
|
||||
return my->get_voters(account_name_or_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");
|
||||
|
||||
|
|
@ -1949,6 +2127,268 @@ 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
|
||||
if(!committee_ids.empty()) {
|
||||
vector< votes_info_object<committee_member_id_type> > votes_for_committee_members;
|
||||
votes_for_committee_members.reserve(committee_ids.size());
|
||||
for (const auto &committee : committee_ids) {
|
||||
const auto &committee_obj = committee.as<committee_member_object>(2);
|
||||
votes_for_committee_members.emplace_back(votes_info_object<committee_member_id_type>{committee_obj.vote_id, committee_obj.id.instance()});
|
||||
}
|
||||
result.votes_for_committee_members = std::move(votes_for_committee_members);
|
||||
}
|
||||
|
||||
if(!witness_ids.empty()) {
|
||||
vector< votes_info_object<witness_id_type> > votes_for_witnesses;
|
||||
votes_for_witnesses.reserve(witness_ids.size());
|
||||
for (const auto &witness : witness_ids) {
|
||||
const auto &witness_obj = witness.as<witness_object>(2);
|
||||
votes_for_witnesses.emplace_back(votes_info_object<witness_id_type>{witness_obj.vote_id, witness_obj.id.instance()});
|
||||
}
|
||||
result.votes_for_witnesses = std::move(votes_for_witnesses);
|
||||
}
|
||||
|
||||
if(!for_worker_ids.empty()) {
|
||||
vector< votes_info_object<worker_id_type> > votes_for_workers;
|
||||
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);
|
||||
votes_for_workers.emplace_back(votes_info_object<worker_id_type>{for_worker_obj.vote_for, for_worker_obj.id.instance()});
|
||||
}
|
||||
result.votes_for_workers = std::move(votes_for_workers);
|
||||
}
|
||||
|
||||
if(!against_worker_ids.empty()) {
|
||||
vector< votes_info_object<worker_id_type> > votes_against_workers;
|
||||
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);
|
||||
votes_against_workers.emplace_back(votes_info_object<worker_id_type>{against_worker_obj.vote_against, against_worker_obj.id.instance()});
|
||||
}
|
||||
result.votes_against_workers = std::move(votes_against_workers);
|
||||
}
|
||||
|
||||
if(!son_ids.empty()) {
|
||||
vector< votes_info_object<son_id_type> > votes_for_sons;
|
||||
votes_for_sons.reserve(son_ids.size());
|
||||
for (const auto &son : son_ids) {
|
||||
const auto &son_obj = son.as<son_object>(6);
|
||||
votes_for_sons.emplace_back(votes_info_object<son_id_type>{son_obj.vote_id, son_obj.id.instance()});
|
||||
}
|
||||
result.votes_for_sons = std::move(votes_for_sons);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
voters_info database_api_impl::get_voters(const string &account_name_or_id) const {
|
||||
voters_info result;
|
||||
|
||||
//! Find account name
|
||||
bool owner_account_found = false;
|
||||
std::string owner_account_id;
|
||||
|
||||
//! Check if we have account by name
|
||||
const auto& account_object = get_account_by_name(account_name_or_id);
|
||||
if(account_object) {
|
||||
//! It is account
|
||||
owner_account_id = object_id_to_string( account_object->get_id() );
|
||||
owner_account_found = true;
|
||||
}
|
||||
else {
|
||||
//! Check if we have account id
|
||||
const auto& account_id = maybe_id<account_id_type>(account_name_or_id);
|
||||
if(account_id) {
|
||||
//! It may be account id
|
||||
const auto& account_objects = get_accounts({account_name_or_id});
|
||||
if(!account_objects.empty()){
|
||||
const auto& account_object = account_objects.front();
|
||||
if(account_object) {
|
||||
//! It is account object
|
||||
owner_account_id = object_id_to_string( account_object->get_id() );
|
||||
owner_account_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
//! Check if we have committee member id
|
||||
const auto& committee_member_id = maybe_id<committee_member_id_type>(account_name_or_id);
|
||||
if(committee_member_id) {
|
||||
//! It may be committee member id
|
||||
const auto& committee_member_objects = get_committee_members({*committee_member_id});
|
||||
if(!committee_member_objects.empty()){
|
||||
const auto& committee_member_object = committee_member_objects.front();
|
||||
if(committee_member_object) {
|
||||
//! It is committee member object
|
||||
owner_account_id = object_id_to_string( committee_member_object->committee_member_account );
|
||||
owner_account_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
//! Check if we have witness id
|
||||
const auto& witness_id = maybe_id<witness_id_type>(account_name_or_id);
|
||||
if(witness_id) {
|
||||
//! It may be witness id
|
||||
const auto& witness_objects = get_witnesses({*witness_id});
|
||||
if(!witness_objects.empty()){
|
||||
const auto& witness_object = witness_objects.front();
|
||||
if(witness_object) {
|
||||
//! It is witness object
|
||||
owner_account_id = object_id_to_string( witness_object->witness_account );
|
||||
owner_account_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
//! Check if we have worker id
|
||||
const auto& worker_id = maybe_id<worker_id_type>(account_name_or_id);
|
||||
if(worker_id) {
|
||||
//! It may be worker id
|
||||
const auto& worker_objects = get_workers({*worker_id});
|
||||
if(!worker_objects.empty()){
|
||||
const auto& worker_object = worker_objects.front();
|
||||
if(worker_object) {
|
||||
//! It is worker object
|
||||
owner_account_id = object_id_to_string( worker_object->worker_account );
|
||||
owner_account_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
//! Check if we have son id
|
||||
const auto& son_id = maybe_id<son_id_type>(account_name_or_id);
|
||||
if(son_id) {
|
||||
//! It may be son id
|
||||
const auto& son_objects = get_sons({*son_id});
|
||||
if(!son_objects.empty()){
|
||||
const auto& son_object = son_objects.front();
|
||||
if(son_object) {
|
||||
//! It is son object
|
||||
owner_account_id = object_id_to_string( son_object->son_account );
|
||||
owner_account_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! We didn't find who it was
|
||||
if(!owner_account_found)
|
||||
FC_THROW_EXCEPTION(database_query_exception, "Wrong account_name_or_id: ${account_name_or_id}", ("account_name_or_id", account_name_or_id));
|
||||
|
||||
//! Fill voters_info
|
||||
const auto& committee_member_object = get_committee_member_by_account(owner_account_id);
|
||||
const auto& witness_object = get_witness_by_account(owner_account_id);
|
||||
const auto& worker_objects = get_workers_by_account(owner_account_id);
|
||||
const auto& son_object = get_son_by_account(owner_account_id);
|
||||
|
||||
//! Info for committee member voters
|
||||
if(committee_member_object) {
|
||||
const auto& committee_member_voters = get_voters_by_id(committee_member_object->vote_id);
|
||||
voters_info_object voters_for_committee_member;
|
||||
voters_for_committee_member.vote_id = committee_member_object->vote_id;
|
||||
voters_for_committee_member.voters.reserve(committee_member_voters.size());
|
||||
for(const auto& voter: committee_member_voters) {
|
||||
voters_for_committee_member.voters.emplace_back(voter.get_id());
|
||||
}
|
||||
result.voters_for_committee_member = std::move(voters_for_committee_member);
|
||||
}
|
||||
|
||||
//! Info for witness voters
|
||||
if(witness_object) {
|
||||
const auto& witness_voters = get_voters_by_id(witness_object->vote_id);
|
||||
voters_info_object voters_for_witness;
|
||||
voters_for_witness.vote_id = witness_object->vote_id;
|
||||
voters_for_witness.voters.reserve(witness_voters.size());
|
||||
for(const auto& voter: witness_voters) {
|
||||
voters_for_witness.voters.emplace_back(voter.get_id());
|
||||
}
|
||||
result.voters_for_witness = std::move(voters_for_witness);
|
||||
}
|
||||
|
||||
//! Info for worker voters
|
||||
if(!worker_objects.empty()) {
|
||||
vector<voters_info_object> voters_for_workers(worker_objects.size());
|
||||
vector<voters_info_object> voters_against_workers(worker_objects.size());
|
||||
for (const auto &worker_object : worker_objects) {
|
||||
voters_info_object voters_for_worker;
|
||||
const auto &for_worker_voters = get_voters_by_id(worker_object.vote_for);
|
||||
voters_for_worker.vote_id = worker_object.vote_for;
|
||||
voters_for_worker.voters.reserve(for_worker_voters.size());
|
||||
for (const auto &voter : for_worker_voters) {
|
||||
voters_for_worker.voters.emplace_back(voter.get_id());
|
||||
}
|
||||
voters_for_workers.emplace_back(std::move(voters_for_worker));
|
||||
|
||||
voters_info_object voters_against_worker;
|
||||
const auto &against_worker_voters = get_voters_by_id(worker_object.vote_against);
|
||||
voters_against_worker.vote_id = worker_object.vote_against;
|
||||
voters_against_worker.voters.reserve(against_worker_voters.size());
|
||||
for (const auto &voter : against_worker_voters) {
|
||||
voters_against_worker.voters.emplace_back(voter.get_id());
|
||||
}
|
||||
voters_against_workers.emplace_back(std::move(voters_against_worker));
|
||||
}
|
||||
result.voters_for_workers = std::move(voters_for_workers);
|
||||
result.voters_against_workers = std::move(voters_against_workers);
|
||||
}
|
||||
|
||||
//! Info for son voters
|
||||
if(son_object) {
|
||||
const auto& son_voters = get_voters_by_id(son_object->vote_id);
|
||||
voters_info_object voters_for_son;
|
||||
voters_for_son.vote_id = son_object->vote_id;
|
||||
voters_for_son.voters.reserve(son_voters.size());
|
||||
for(const auto& voter: son_voters) {
|
||||
voters_for_son.voters.emplace_back(voter.get_id());
|
||||
}
|
||||
result.voters_for_son = std::move(voters_for_son);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Authority / validation //
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@
|
|||
#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/chain/voters_info.hpp>
|
||||
|
||||
#include <graphene/market_history/market_history_plugin.hpp>
|
||||
|
||||
|
|
@ -558,6 +560,13 @@ public:
|
|||
* @param account The ID of the account whose witness should be retrieved
|
||||
* @return The witness object, or null if the account does not have a witness
|
||||
*/
|
||||
fc::optional<witness_object> get_witness_by_account_id(account_id_type account) const;
|
||||
|
||||
/**
|
||||
* @brief Get the witness owned by a given account
|
||||
* @param account_id_or_name The ID or name of the account whose witness should be retrieved
|
||||
* @return The witness object, or null if the account does not have a witness
|
||||
*/
|
||||
fc::optional<witness_object> get_witness_by_account(const std::string account_name_or_id) const;
|
||||
|
||||
/**
|
||||
|
|
@ -586,6 +595,13 @@ public:
|
|||
*/
|
||||
vector<optional<committee_member_object>> get_committee_members(const vector<committee_member_id_type> &committee_member_ids) const;
|
||||
|
||||
/**
|
||||
* @brief Get the committee_member owned by a given account
|
||||
* @param account The ID of the account whose committee_member should be retrieved
|
||||
* @return The committee_member object, or null if the account does not have a committee_member
|
||||
*/
|
||||
fc::optional<committee_member_object> get_committee_member_by_account_id(account_id_type account) const;
|
||||
|
||||
/**
|
||||
* @brief Get the committee_member owned by a given account
|
||||
* @param account_id_or_name The ID or name of the account whose committee_member should be retrieved
|
||||
|
|
@ -601,6 +617,11 @@ public:
|
|||
*/
|
||||
map<string, committee_member_id_type> lookup_committee_member_accounts(const string &lower_bound_name, uint32_t limit) const;
|
||||
|
||||
/**
|
||||
* @brief Get the total number of committee_members registered with the blockchain
|
||||
*/
|
||||
uint64_t get_committee_member_count() const;
|
||||
|
||||
/////////////////
|
||||
// SON members //
|
||||
/////////////////
|
||||
|
|
@ -619,7 +640,14 @@ public:
|
|||
* @param account The ID of the account whose SON should be retrieved
|
||||
* @return The SON object, or null if the account does not have a SON
|
||||
*/
|
||||
fc::optional<son_object> get_son_by_account(account_id_type account) const;
|
||||
fc::optional<son_object> get_son_by_account_id(account_id_type account) const;
|
||||
|
||||
/**
|
||||
* @brief Get the SON owned by a given account
|
||||
* @param account_id_or_name The ID of the account whose SON should be retrieved
|
||||
* @return The SON object, or null if the account does not have a SON
|
||||
*/
|
||||
fc::optional<son_object> get_son_by_account(const std::string account_id_or_name) const;
|
||||
|
||||
/**
|
||||
* @brief Get names and IDs for registered SONs
|
||||
|
|
@ -698,15 +726,46 @@ public:
|
|||
*/
|
||||
uint64_t get_sidechain_addresses_count() const;
|
||||
|
||||
/// WORKERS
|
||||
/////////////
|
||||
// Workers //
|
||||
/////////////
|
||||
|
||||
/**
|
||||
* @brief Get a list of workers by ID
|
||||
* @param worker_ids IDs of the workers to retrieve
|
||||
* @return The workers corresponding to the provided IDs
|
||||
*
|
||||
* This function has semantics identical to @ref get_objects
|
||||
*/
|
||||
vector<optional<worker_object>> get_workers(const vector<worker_id_type> &worker_ids) const;
|
||||
|
||||
/**
|
||||
* @brief Return the worker objects associated with this account.
|
||||
* @param account_id_or_name The ID or name of the account whose worker should be retrieved
|
||||
* @param account The ID of the account whose workers should be retrieved
|
||||
* @return The worker object or null if the account does not have a worker
|
||||
*/
|
||||
vector<worker_object> get_workers_by_account_id(account_id_type account) const;
|
||||
|
||||
/**
|
||||
* @brief Return the worker objects associated with this account.
|
||||
* @param account_id_or_name The ID or name of the account whose workers should be retrieved
|
||||
* @return The worker object or null if the account does not have a worker
|
||||
*/
|
||||
vector<worker_object> get_workers_by_account(const std::string account_id_or_name) const;
|
||||
|
||||
/**
|
||||
* @brief Get names and IDs for registered workers
|
||||
* @param lower_bound_name Lower bound of the first name to return
|
||||
* @param limit Maximum number of results to return -- must not exceed 1000
|
||||
* @return Map of worker names to corresponding IDs
|
||||
*/
|
||||
map<string, worker_id_type> lookup_worker_accounts(const string &lower_bound_name, uint32_t limit) const;
|
||||
|
||||
/**
|
||||
* @brief Get the total number of workers registered with the blockchain
|
||||
*/
|
||||
uint64_t get_worker_count() const;
|
||||
|
||||
///////////
|
||||
// Votes //
|
||||
///////////
|
||||
|
|
@ -721,6 +780,39 @@ public:
|
|||
*/
|
||||
vector<variant> lookup_vote_ids(const vector<vote_id_type> &votes) 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;
|
||||
|
||||
/**
|
||||
* @brief Return the accounts that votes for account_name_or_id
|
||||
* @param account_name_or_id ID or name of the account to get voters for
|
||||
* @return The voters_info for account_name_or_id
|
||||
*
|
||||
*/
|
||||
voters_info get_voters(const string &account_name_or_id) const;
|
||||
|
||||
////////////////////////////
|
||||
// Authority / validation //
|
||||
////////////////////////////
|
||||
|
|
@ -1033,17 +1125,21 @@ FC_API(graphene::app::database_api,
|
|||
|
||||
// Witnesses
|
||||
(get_witnesses)
|
||||
(get_witness_by_account_id)
|
||||
(get_witness_by_account)
|
||||
(lookup_witness_accounts)
|
||||
(get_witness_count)
|
||||
|
||||
// Committee members
|
||||
(get_committee_members)
|
||||
(get_committee_member_by_account_id)
|
||||
(get_committee_member_by_account)
|
||||
(lookup_committee_member_accounts)
|
||||
(get_committee_member_count)
|
||||
|
||||
// SON members
|
||||
(get_sons)
|
||||
(get_son_by_account_id)
|
||||
(get_son_by_account)
|
||||
(lookup_son_accounts)
|
||||
(get_son_count)
|
||||
|
|
@ -1060,10 +1156,19 @@ FC_API(graphene::app::database_api,
|
|||
(get_sidechain_address_by_account_and_sidechain)
|
||||
(get_sidechain_addresses_count)
|
||||
|
||||
// workers
|
||||
// Workers
|
||||
(get_workers)
|
||||
(get_workers_by_account_id)
|
||||
(get_workers_by_account)
|
||||
(lookup_worker_accounts)
|
||||
(get_worker_count)
|
||||
|
||||
// Votes
|
||||
(lookup_vote_ids)
|
||||
(get_votes_ids)
|
||||
(get_votes)
|
||||
(get_voters_by_id)
|
||||
(get_voters)
|
||||
|
||||
// Authority / validation
|
||||
(get_transaction_hex)
|
||||
|
|
|
|||
40
libraries/chain/include/graphene/chain/voters_info.hpp
Normal file
40
libraries/chain/include/graphene/chain/voters_info.hpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include <graphene/protocol/vote.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
/**
|
||||
* @class voters_info_object
|
||||
* @ingroup object
|
||||
*/
|
||||
struct voters_info_object {
|
||||
vote_id_type vote_id;
|
||||
vector<account_id_type> voters;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class voters_info
|
||||
* @brief tracks information about a voters info
|
||||
* @ingroup object
|
||||
*/
|
||||
struct voters_info {
|
||||
optional<voters_info_object> voters_for_committee_member;
|
||||
optional<voters_info_object> voters_for_witness;
|
||||
optional<vector<voters_info_object> > voters_for_workers;
|
||||
optional<vector<voters_info_object> > voters_against_workers;
|
||||
optional<voters_info_object> voters_for_son;
|
||||
};
|
||||
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT( graphene::chain::voters_info_object,
|
||||
(vote_id)
|
||||
(voters) )
|
||||
|
||||
FC_REFLECT( graphene::chain::voters_info,
|
||||
(voters_for_committee_member)
|
||||
(voters_for_witness)
|
||||
(voters_for_workers)
|
||||
(voters_against_workers)
|
||||
(voters_for_son) )
|
||||
48
libraries/chain/include/graphene/chain/votes_info.hpp
Normal file
48
libraries/chain/include/graphene/chain/votes_info.hpp
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#include <graphene/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 {
|
||||
optional< vector< votes_info_object<committee_member_id_type> > > votes_for_committee_members;
|
||||
optional< vector< votes_info_object<witness_id_type> > > votes_for_witnesses;
|
||||
optional< vector< votes_info_object<worker_id_type> > > votes_for_workers;
|
||||
optional< vector< votes_info_object<worker_id_type> > > votes_against_workers;
|
||||
optional< 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) )
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit a17b231acf3bbd448179ddffc63c655e9b326395
|
||||
Subproject commit bff16bbc3dcecbb9ddec96ba0af99ae33a3bf528
|
||||
|
|
@ -23,19 +23,11 @@ add_library( peerplays_sidechain
|
|||
)
|
||||
|
||||
if (ENABLE_DEV_FEATURES)
|
||||
set(ENABLE_MULTIPLE_SONS 1)
|
||||
set(ENABLE_PEERPLAYS_ASSET_DEPOSITS 1)
|
||||
endif()
|
||||
unset(ENABLE_DEV_FEATURES)
|
||||
unset(ENABLE_DEV_FEATURES CACHE)
|
||||
|
||||
if (ENABLE_MULTIPLE_SONS)
|
||||
message ("Multiple SONs per software instance are supported")
|
||||
target_compile_definitions(peerplays_sidechain PRIVATE ENABLE_MULTIPLE_SONS)
|
||||
endif()
|
||||
unset(ENABLE_MULTIPLE_SONS)
|
||||
unset(ENABLE_MULTIPLE_SONS CACHE)
|
||||
|
||||
if (ENABLE_PEERPLAYS_ASSET_DEPOSITS)
|
||||
message ("Depositing Peerplays assets enabled")
|
||||
target_compile_definitions(peerplays_sidechain PRIVATE ENABLE_PEERPLAYS_ASSET_DEPOSITS)
|
||||
|
|
|
|||
|
|
@ -177,12 +177,6 @@ void peerplays_sidechain_plugin_impl::plugin_initialize(const boost::program_opt
|
|||
}
|
||||
config_ready_son = config_ready_son && !sons.empty();
|
||||
|
||||
#ifndef ENABLE_MULTIPLE_SONS
|
||||
if (sons.size() > 1) {
|
||||
FC_THROW("Invalid configuration, multiple SON IDs provided");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (options.count("peerplays-private-key")) {
|
||||
const std::vector<std::string> key_id_to_wif_pair_strings = options["peerplays-private-key"].as<std::vector<std::string>>();
|
||||
for (const std::string &key_id_to_wif_pair_string : key_id_to_wif_pair_strings) {
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ void sidechain_net_handler::settle_sidechain_transactions() {
|
|||
if (settle_amount.amount != 0) {
|
||||
if (sto.object_id.is<son_wallet_deposit_id_type>()) {
|
||||
asset_issue_operation ai_op;
|
||||
ai_op.fee = asset(2001000);
|
||||
ai_op.fee = database.current_fee_schedule().calculate_fee(ai_op);
|
||||
ai_op.issuer = gpo.parameters.son_account();
|
||||
ai_op.asset_to_issue = settle_amount;
|
||||
ai_op.issue_to_account = database.get<son_wallet_deposit_object>(sto.object_id).peerplays_from;
|
||||
|
|
@ -598,7 +598,7 @@ void sidechain_net_handler::settle_sidechain_transactions() {
|
|||
|
||||
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
||||
asset_reserve_operation ar_op;
|
||||
ar_op.fee = asset(2001000);
|
||||
ar_op.fee = database.current_fee_schedule().calculate_fee(ar_op);
|
||||
ar_op.payer = gpo.parameters.son_account();
|
||||
ar_op.amount_to_reserve = settle_amount;
|
||||
proposal_op.proposed_ops.emplace_back(ar_op);
|
||||
|
|
|
|||
|
|
@ -626,7 +626,7 @@ bool sidechain_net_handler_hive::process_deposit(const son_wallet_deposit_object
|
|||
proposal_op.proposed_ops.emplace_back(swdp_op);
|
||||
|
||||
asset_issue_operation ai_op;
|
||||
ai_op.fee = asset(2001000);
|
||||
ai_op.fee = database.current_fee_schedule().calculate_fee(ai_op);
|
||||
ai_op.issuer = gpo.parameters.son_account();
|
||||
ai_op.asset_to_issue = asset_to_issue;
|
||||
ai_op.issue_to_account = swdo.peerplays_from;
|
||||
|
|
|
|||
|
|
@ -1346,6 +1346,21 @@ class wallet_api
|
|||
*/
|
||||
map<string, committee_member_id_type> list_committee_members(const string& lowerbound, uint32_t limit);
|
||||
|
||||
/** Lists all workers in the blockchain.
|
||||
* This returns a list of all account names that own worker, and the associated worker id,
|
||||
* sorted by name. This lists workers whether they are currently voted in or not.
|
||||
*
|
||||
* Use the \c lowerbound and limit parameters to page through the list. To retrieve all workers,
|
||||
* start by setting \c lowerbound to the empty string \c "", and then each iteration, pass
|
||||
* the last worker name returned as the \c lowerbound for the next \c list_workers() call.
|
||||
*
|
||||
* @param lowerbound the name of the first worker to return. If the named worker does not exist,
|
||||
* the list will start at the worker that comes after \c lowerbound
|
||||
* @param limit the maximum number of worker to return (max: 1000)
|
||||
* @returns a list of worker mapping worker names to worker ids
|
||||
*/
|
||||
map<string, worker_id_type> list_workers(const string& lowerbound, uint32_t limit);
|
||||
|
||||
/** Returns information about the given SON.
|
||||
* @param owner_account the name or id of the SON account owner, or the id of the SON
|
||||
* @returns the information about the SON stored in the block chain
|
||||
|
|
@ -1370,6 +1385,12 @@ class wallet_api
|
|||
*/
|
||||
committee_member_object get_committee_member(string owner_account);
|
||||
|
||||
/** Returns information about the given worker.
|
||||
* @param owner_account the name or id of the worker account owner, or the id of the worker
|
||||
* @returns the information about the workers stored in the block chain
|
||||
*/
|
||||
vector<worker_object> get_workers(string owner_account);
|
||||
|
||||
|
||||
/** Creates a SON object owned by the given account.
|
||||
*
|
||||
|
|
@ -2490,9 +2511,41 @@ 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;
|
||||
|
||||
/**
|
||||
* @brief Return the accounts that votes for account_name_or_id
|
||||
* @param account_name_or_id ID or name of the account to get voters for
|
||||
* @return The voters_info for account_name_or_id
|
||||
*
|
||||
*/
|
||||
voters_info get_voters(const string &account_name_or_id) const;
|
||||
|
||||
|
||||
fc::signal<void(bool)> lock_changed;
|
||||
std::shared_ptr<detail::wallet_api_impl> my;
|
||||
void encrypt_keys();
|
||||
|
|
@ -2629,8 +2682,10 @@ FC_API( graphene::wallet::wallet_api,
|
|||
(get_witness)
|
||||
(is_witness)
|
||||
(get_committee_member)
|
||||
(get_workers)
|
||||
(list_witnesses)
|
||||
(list_committee_members)
|
||||
(list_workers)
|
||||
(create_son)
|
||||
(try_create_son)
|
||||
(update_son)
|
||||
|
|
@ -2799,4 +2854,8 @@ FC_API( graphene::wallet::wallet_api,
|
|||
(get_custom_account_authorities_by_permission_name)
|
||||
(get_active_custom_account_authorities_by_operation)
|
||||
(run_custom_operation)
|
||||
(get_votes_ids)
|
||||
(get_votes)
|
||||
(get_voters_by_id)
|
||||
(get_voters)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1954,7 +1954,7 @@ public:
|
|||
try
|
||||
{
|
||||
account_id_type owner_account_id = get_account_id(owner_account);
|
||||
fc::optional<son_object> son = _remote_db->get_son_by_account(owner_account_id);
|
||||
fc::optional<son_object> son = _remote_db->get_son_by_account_id(owner_account_id);
|
||||
if (son)
|
||||
return *son;
|
||||
else
|
||||
|
|
@ -1969,6 +1969,49 @@ public:
|
|||
FC_CAPTURE_AND_RETHROW( (owner_account) )
|
||||
}
|
||||
|
||||
vector<worker_object> get_workers(string owner_account)
|
||||
{
|
||||
try
|
||||
{
|
||||
fc::optional<worker_id_type> worker_id = maybe_id<worker_id_type>(owner_account);
|
||||
if (worker_id)
|
||||
{
|
||||
std::vector<worker_id_type> ids_to_get;
|
||||
ids_to_get.push_back(*worker_id);
|
||||
std::vector<fc::optional<worker_object>> worker_objects = _remote_db->get_workers(ids_to_get);
|
||||
|
||||
if(!worker_objects.empty()) {
|
||||
std::vector<worker_object> result;
|
||||
for (const auto &worker_object : worker_objects) {
|
||||
if (worker_object)
|
||||
result.emplace_back(*worker_object);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
FC_THROW("No workers is registered for id ${id}", ("id", owner_account));
|
||||
}
|
||||
else
|
||||
{
|
||||
// then maybe it's the owner account
|
||||
try
|
||||
{
|
||||
std::string owner_account_id = account_id_to_string(get_account_id(owner_account));
|
||||
auto workers = _remote_db->get_workers_by_account(owner_account_id);
|
||||
if (!workers.empty())
|
||||
return workers;
|
||||
else
|
||||
FC_THROW("No workers is registered for account ${account}", ("account", owner_account));
|
||||
}
|
||||
catch (const fc::exception&)
|
||||
{
|
||||
FC_THROW("No account or worker named ${account}", ("account", owner_account));
|
||||
}
|
||||
}
|
||||
}
|
||||
FC_CAPTURE_AND_RETHROW( (owner_account) )
|
||||
}
|
||||
|
||||
bool is_witness(string owner_account)
|
||||
{
|
||||
try
|
||||
|
|
@ -2083,7 +2126,7 @@ public:
|
|||
son_create_op.pay_vb = pay_vb_id;
|
||||
son_create_op.sidechain_public_keys = sidechain_public_keys;
|
||||
|
||||
if (_remote_db->get_son_by_account(son_create_op.owner_account))
|
||||
if (_remote_db->get_son_by_account_id(son_create_op.owner_account))
|
||||
FC_THROW("Account ${owner_account} is already a SON", ("owner_account", owner_account));
|
||||
|
||||
signed_transaction tx;
|
||||
|
|
@ -2720,7 +2763,7 @@ public:
|
|||
|
||||
account_object voting_account_object = get_account(voting_account);
|
||||
account_id_type son_account_id = get_account_id(son);
|
||||
fc::optional<son_object> son_obj = _remote_db->get_son_by_account(son_account_id);
|
||||
fc::optional<son_object> son_obj = _remote_db->get_son_by_account_id(son_account_id);
|
||||
if (!son_obj)
|
||||
FC_THROW("Account ${son} is not registered as a son", ("son", son));
|
||||
if (approve)
|
||||
|
|
@ -2765,7 +2808,7 @@ public:
|
|||
for (const std::string& son : sons_to_approve)
|
||||
{
|
||||
account_id_type son_owner_account_id = get_account_id(son);
|
||||
fc::optional<son_object> son_obj = _remote_db->get_son_by_account(son_owner_account_id);
|
||||
fc::optional<son_object> son_obj = _remote_db->get_son_by_account_id(son_owner_account_id);
|
||||
if (!son_obj)
|
||||
FC_THROW("Account ${son} is not registered as a SON", ("son", son));
|
||||
auto insert_result = voting_account_object.options.votes.insert(son_obj->vote_id);
|
||||
|
|
@ -2775,7 +2818,7 @@ public:
|
|||
for (const std::string& son : sons_to_reject)
|
||||
{
|
||||
account_id_type son_owner_account_id = get_account_id(son);
|
||||
fc::optional<son_object> son_obj = _remote_db->get_son_by_account(son_owner_account_id);
|
||||
fc::optional<son_object> son_obj = _remote_db->get_son_by_account_id(son_owner_account_id);
|
||||
if (!son_obj)
|
||||
FC_THROW("Account ${son} is not registered as a SON", ("son", son));
|
||||
unsigned votes_removed = voting_account_object.options.votes.erase(son_obj->vote_id);
|
||||
|
|
@ -4090,6 +4133,42 @@ 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) )
|
||||
}
|
||||
|
||||
voters_info get_voters(const string &account_name_or_id) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return _remote_db->get_voters(account_name_or_id);
|
||||
}
|
||||
FC_CAPTURE_AND_RETHROW( (account_name_or_id) )
|
||||
}
|
||||
|
||||
string _wallet_filename;
|
||||
wallet_data _wallet;
|
||||
|
||||
|
|
@ -4999,6 +5078,11 @@ map<string,committee_member_id_type> wallet_api::list_committee_members(const st
|
|||
return my->_remote_db->lookup_committee_member_accounts(lowerbound, limit);
|
||||
}
|
||||
|
||||
map<string, worker_id_type> wallet_api::list_workers(const string& lowerbound, uint32_t limit)
|
||||
{
|
||||
return my->_remote_db->lookup_worker_accounts(lowerbound, limit);
|
||||
}
|
||||
|
||||
son_object wallet_api::get_son(string owner_account)
|
||||
{
|
||||
return my->get_son(owner_account);
|
||||
|
|
@ -5019,6 +5103,11 @@ committee_member_object wallet_api::get_committee_member(string owner_account)
|
|||
return my->get_committee_member(owner_account);
|
||||
}
|
||||
|
||||
vector<worker_object> wallet_api::get_workers(string owner_account)
|
||||
{
|
||||
return my->get_workers(owner_account);
|
||||
}
|
||||
|
||||
signed_transaction wallet_api::create_vesting_balance(string owner_account,
|
||||
string amount,
|
||||
string asset_symbol,
|
||||
|
|
@ -7617,6 +7706,26 @@ 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);
|
||||
}
|
||||
|
||||
voters_info wallet_api::get_voters(const string &account_name_or_id) const
|
||||
{
|
||||
return my->get_voters(account_name_or_id);
|
||||
}
|
||||
|
||||
// default ctor necessary for FC_REFLECT
|
||||
signed_block_with_info::signed_block_with_info( const signed_block& block )
|
||||
: signed_block( block )
|
||||
|
|
|
|||
|
|
@ -244,6 +244,28 @@ BOOST_AUTO_TEST_CASE( son_voting )
|
|||
son2_end_votes = son2_obj.total_votes;
|
||||
BOOST_CHECK(son2_end_votes > son2_start_votes);
|
||||
|
||||
//! Get nathan account
|
||||
const auto nathan_account_object = con.wallet_api_ptr->get_account("nathan");
|
||||
|
||||
//! Check son1account voters
|
||||
auto voters_for_son1account = con.wallet_api_ptr->get_voters("son1account");
|
||||
BOOST_REQUIRE(voters_for_son1account.voters_for_son);
|
||||
BOOST_CHECK_EQUAL(voters_for_son1account.voters_for_son->voters.size(), 1);
|
||||
BOOST_CHECK_EQUAL((uint32_t)voters_for_son1account.voters_for_son->voters[0].instance, nathan_account_object.id.instance());
|
||||
|
||||
//! Check son2account voters
|
||||
auto voters_for_son2account = con.wallet_api_ptr->get_voters("son2account");
|
||||
BOOST_REQUIRE(voters_for_son2account.voters_for_son);
|
||||
BOOST_CHECK_EQUAL(voters_for_son2account.voters_for_son->voters.size(), 1);
|
||||
BOOST_CHECK_EQUAL((uint32_t)voters_for_son2account.voters_for_son->voters[0].instance, nathan_account_object.id.instance());
|
||||
|
||||
//! Check votes of nathan
|
||||
auto nathan_votes = con.wallet_api_ptr->get_votes("nathan");
|
||||
BOOST_REQUIRE(nathan_votes.votes_for_sons);
|
||||
BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->size(), 2);
|
||||
BOOST_CHECK_EQUAL((uint32_t)nathan_votes.votes_for_sons->at(0).id.instance, son1_obj.id.instance());
|
||||
BOOST_CHECK_EQUAL((uint32_t)nathan_votes.votes_for_sons->at(1).id.instance, son2_obj.id.instance());
|
||||
|
||||
// Withdraw vote for a son1account
|
||||
BOOST_TEST_MESSAGE("Withdraw vote for a son1account");
|
||||
vote_son1_tx = con.wallet_api_ptr->vote_for_son("nathan", "son1account", false, true);
|
||||
|
|
@ -254,6 +276,17 @@ BOOST_AUTO_TEST_CASE( son_voting )
|
|||
son1_end_votes = son1_obj.total_votes;
|
||||
BOOST_CHECK(son1_end_votes == son1_start_votes);
|
||||
|
||||
//! Check son1account voters
|
||||
voters_for_son1account = con.wallet_api_ptr->get_voters("son1account");
|
||||
BOOST_REQUIRE(voters_for_son1account.voters_for_son);
|
||||
BOOST_CHECK_EQUAL(voters_for_son1account.voters_for_son->voters.size(), 0);
|
||||
|
||||
//! Check votes of nathan
|
||||
nathan_votes = con.wallet_api_ptr->get_votes("nathan");
|
||||
BOOST_REQUIRE(nathan_votes.votes_for_sons);
|
||||
BOOST_CHECK_EQUAL(nathan_votes.votes_for_sons->size(), 1);
|
||||
BOOST_CHECK_EQUAL((uint32_t)nathan_votes.votes_for_sons->at(0).id.instance, son2_obj.id.instance());
|
||||
|
||||
// Withdraw vote for a son2account
|
||||
BOOST_TEST_MESSAGE("Withdraw vote for a son2account");
|
||||
vote_son2_tx = con.wallet_api_ptr->vote_for_son("nathan", "son2account", false, true);
|
||||
|
|
@ -264,6 +297,15 @@ BOOST_AUTO_TEST_CASE( son_voting )
|
|||
son2_end_votes = son2_obj.total_votes;
|
||||
BOOST_CHECK(son2_end_votes == son2_start_votes);
|
||||
|
||||
//! Check son2account voters
|
||||
voters_for_son2account = con.wallet_api_ptr->get_voters("son2account");
|
||||
BOOST_REQUIRE(voters_for_son2account.voters_for_son);
|
||||
BOOST_CHECK_EQUAL(voters_for_son2account.voters_for_son->voters.size(), 0);
|
||||
|
||||
//! Check votes of nathan
|
||||
nathan_votes = con.wallet_api_ptr->get_votes("nathan");
|
||||
BOOST_CHECK(!nathan_votes.votes_for_sons.valid());
|
||||
|
||||
} catch( fc::exception& e ) {
|
||||
BOOST_TEST_MESSAGE("SON cli wallet tests exception");
|
||||
edump((e.to_detail_string()));
|
||||
|
|
|
|||
|
|
@ -322,6 +322,18 @@ BOOST_AUTO_TEST_CASE(track_votes_witnesses_enabled)
|
|||
auto witness1_object = db_api1.get_witness_by_account(witness1_id(db).name);
|
||||
BOOST_CHECK_EQUAL(witness1_object->total_votes, 111);
|
||||
|
||||
//! Check witness1 voters
|
||||
const auto voters_for_witness1 = db_api1.get_voters("witness1");
|
||||
BOOST_REQUIRE(voters_for_witness1.voters_for_witness);
|
||||
BOOST_CHECK_EQUAL(voters_for_witness1.voters_for_witness->voters.size(), 1);
|
||||
BOOST_CHECK_EQUAL((uint32_t)voters_for_witness1.voters_for_witness->voters[0].instance, 18);
|
||||
|
||||
//! Check votes of account
|
||||
const auto account_votes = db_api1.get_votes("1.2.18");
|
||||
BOOST_REQUIRE(account_votes.votes_for_witnesses);
|
||||
BOOST_CHECK_EQUAL(account_votes.votes_for_witnesses->size(), 1);
|
||||
BOOST_CHECK_EQUAL((uint32_t)account_votes.votes_for_witnesses->at(0).id.instance, witness1_object->id.instance());
|
||||
|
||||
} FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
||||
|
|
@ -501,6 +513,17 @@ BOOST_AUTO_TEST_CASE(track_votes_committee_enabled)
|
|||
auto committee1_object = db_api1.get_committee_member_by_account(committee1_id(db).name);
|
||||
BOOST_CHECK_EQUAL(committee1_object->total_votes, 111);
|
||||
|
||||
//! Check committee1 voters
|
||||
const auto voters_for_committee1 = db_api1.get_voters("committee1");
|
||||
BOOST_REQUIRE(voters_for_committee1.voters_for_committee_member);
|
||||
BOOST_CHECK_EQUAL(voters_for_committee1.voters_for_committee_member->voters.size(), 1);
|
||||
BOOST_CHECK_EQUAL((uint32_t)voters_for_committee1.voters_for_committee_member->voters[0].instance, 18);
|
||||
|
||||
//! Check votes of account
|
||||
const auto account_votes = db_api1.get_votes("1.2.18");
|
||||
BOOST_REQUIRE(account_votes.votes_for_committee_members);
|
||||
BOOST_CHECK_EQUAL((uint32_t)account_votes.votes_for_committee_members->back().id.instance, committee1_object->id.instance());
|
||||
|
||||
} FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue