From 339adbb0549b9135bdfe856ee83a737d1ec55eb6 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Fri, 11 Feb 2022 15:41:47 +0000 Subject: [PATCH] #270 functions to unified form --- libraries/app/database_api.cpp | 102 ++++++++++++++++-- .../app/include/graphene/app/database_api.hpp | 49 ++++++++- .../wallet/include/graphene/wallet/wallet.hpp | 23 ++++ libraries/wallet/wallet.cpp | 53 +++++++++ 4 files changed, 214 insertions(+), 13 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 632f74b9d..20f5fe2e3 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -170,14 +170,17 @@ class database_api_impl : public std::enable_shared_from_this // Witnesses vector> get_witnesses(const vector &witness_ids) const; + fc::optional get_witness_by_account_id(account_id_type account) const; fc::optional get_witness_by_account(const std::string account_id_or_name) const; map lookup_witness_accounts(const string &lower_bound_name, uint32_t limit) const; uint64_t get_witness_count() const; // Committee members vector> get_committee_members(const vector &committee_member_ids) const; + fc::optional get_committee_member_by_account_id(account_id_type account) const; fc::optional get_committee_member_by_account(const std::string account_id_or_name) const; map lookup_committee_member_accounts(const string &lower_bound_name, uint32_t limit) const; + uint64_t get_committee_member_count() const; // SON members vector> get_sons(const vector &son_ids) const; @@ -200,7 +203,10 @@ class database_api_impl : public std::enable_shared_from_this // Workers vector> get_workers(const vector &witness_ids) const; + vector get_workers_by_account_id(account_id_type account) const; vector get_workers_by_account(const std::string account_id_or_name) const; + map lookup_worker_accounts(const string &lower_bound_name, uint32_t limit) const; + uint64_t get_worker_count() const; // Votes vector lookup_vote_ids(const vector &votes) const; @@ -292,6 +298,8 @@ class database_api_impl : public std::enable_shared_from_this 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; @@ -1611,19 +1619,27 @@ vector> database_api_impl::get_witnesses(const vector 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 database_api::get_witness_by_account_id(account_id_type account) const { + return my->get_witness_by_account_id(account); } -fc::optional database_api_impl::get_witness_by_account(const std::string account_id_or_name) const { +fc::optional database_api_impl::get_witness_by_account_id(account_id_type account) const { const auto &idx = _db.get_index_type().indices().get(); - 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 {}; } +fc::optional 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 database_api_impl::get_witness_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_witness_by_account_id(account); +} + map database_api::lookup_witness_accounts(const string &lower_bound_name, uint32_t limit) const { return my->lookup_witness_accounts(lower_bound_name, limit); } @@ -1682,19 +1698,27 @@ vector> database_api_impl::get_committee_membe return result; } -fc::optional 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 database_api::get_committee_member_by_account_id(account_id_type account) const { + return my->get_committee_member_by_account_id(account); } -fc::optional database_api_impl::get_committee_member_by_account(const std::string account_id_or_name) const { +fc::optional database_api_impl::get_committee_member_by_account_id(account_id_type account) const { const auto &idx = _db.get_index_type().indices().get(); - 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 {}; } +fc::optional 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 database_api_impl::get_committee_member_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_committee_member_by_account_id(account); +} + map database_api::lookup_committee_member_accounts(const string &lower_bound_name, uint32_t limit) const { return my->lookup_committee_member_accounts(lower_bound_name, limit); } @@ -1723,6 +1747,14 @@ map 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().indices().size(); +} + ////////////////////////////////////////////////////////////////////// // // // SON members // @@ -1771,7 +1803,10 @@ map database_api::lookup_son_accounts(const string &lower_b } map 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().indices().get(); // we want to order sons by account name, but that name is in the account object @@ -1927,10 +1962,22 @@ vector> database_api::get_workers(const vectorget_workers(worker_ids); } +vector database_api::get_workers_by_account_id(account_id_type account) const { + return my->get_workers_by_account_id(account); +} + vector 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 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> database_api_impl::get_workers(const vector &worker_ids) const { vector> result; result.reserve(worker_ids.size()); @@ -1943,9 +1990,8 @@ vector> database_api_impl::get_workers(const vector database_api_impl::get_workers_by_account(const std::string account_id_or_name) const { +vector database_api_impl::get_workers_by_account_id(account_id_type account) const { const auto &idx = _db.get_index_type().indices().get(); - const account_id_type account = get_account_from_string(account_id_or_name)->id; auto itr = idx.find(account); vector result; @@ -1957,6 +2003,40 @@ vector database_api_impl::get_workers_by_account(const std::strin return result; } +vector 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 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().indices().get(); + + // 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 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().indices().size(); +} + ////////////////////////////////////////////////////////////////////// // // // Votes // diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 0c9d10f2e..05f427079 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -560,6 +560,13 @@ class database_api { * @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 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 get_witness_by_account(const std::string account_name_or_id) const; /** @@ -588,6 +595,13 @@ class database_api { */ vector> get_committee_members(const vector &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 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 @@ -603,6 +617,11 @@ class database_api { */ map 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 // ///////////////// @@ -625,7 +644,7 @@ class database_api { /** * @brief Get the SON owned by a given account - * @param account The ID of the account whose SON should be retrieved + * @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 get_son_by_account(const std::string account_id_or_name) const; @@ -722,11 +741,31 @@ class database_api { /** * @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 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 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 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 // /////////// @@ -1086,14 +1125,17 @@ 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) @@ -1116,7 +1158,10 @@ FC_API(graphene::app::database_api, // Workers (get_workers) + (get_workers_by_account_id) (get_workers_by_account) + (lookup_worker_accounts) + (get_worker_count) // Votes (lookup_vote_ids) diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 4df3dea69..4b5013a8a 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1346,6 +1346,21 @@ class wallet_api */ map 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 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 get_workers(string owner_account); + /** Creates a SON object owned by the given account. * @@ -2658,8 +2679,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) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 0d865c782..5810985ce 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -1961,6 +1961,49 @@ class wallet_api_impl FC_CAPTURE_AND_RETHROW( (owner_account) ) } + vector get_workers(string owner_account) + { + try + { + fc::optional worker_id = maybe_id(owner_account); + if (worker_id) + { + std::vector ids_to_get; + ids_to_get.push_back(*worker_id); + std::vector> worker_objects = _remote_db->get_workers(ids_to_get); + + if(!worker_objects.empty()) { + std::vector 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 @@ -5027,6 +5070,11 @@ map wallet_api::list_committee_members(const st return my->_remote_db->lookup_committee_member_accounts(lowerbound, limit); } +map 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); @@ -5047,6 +5095,11 @@ committee_member_object wallet_api::get_committee_member(string owner_account) return my->get_committee_member(owner_account); } +vector 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,