diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 5ea958a6..336cc8eb 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -201,7 +201,7 @@ public: // Workers vector> get_workers(const vector &witness_ids) const; - fc::optional get_worker_by_account(const std::string account_id_or_name) 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; @@ -1943,8 +1943,8 @@ vector> database_api::get_workers(const vectorget_workers(worker_ids); } -fc::optional database_api::get_worker_by_account(const std::string account_id_or_name) const { - return my->get_worker_by_account(account_id_or_name); +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 { @@ -1967,13 +1967,18 @@ vector> database_api_impl::get_workers(const vector database_api_impl::get_worker_by_account(const std::string account_id_or_name) const { +vector database_api_impl::get_workers_by_account(const std::string account_id_or_name) 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 {}; + vector result; + + if (itr != idx.end() && itr->worker_account == account) { + result.emplace_back(*itr); + ++itr; + } + + return result; } map database_api_impl::lookup_worker_accounts(const string &lower_bound_name, uint32_t limit) const { @@ -2116,35 +2121,54 @@ votes_info database_api_impl::get_votes(const string &account_name_or_id) const const auto& son_ids = get_votes_objects(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(2); - result.votes_for_committee_members.emplace_back( votes_info_object{ committee_obj.vote_id, committee_obj.id.instance() } ); + if(!committee_ids.empty()) { + vector< votes_info_object > votes_for_committee_members; + votes_for_committee_members.reserve(committee_ids.size()); + for (const auto &committee : committee_ids) { + const auto &committee_obj = committee.as(2); + votes_for_committee_members.emplace_back(votes_info_object{committee_obj.vote_id, committee_obj.id.instance()}); + } + result.votes_for_committee_members = std::move(votes_for_committee_members); } - result.votes_for_witnesses.reserve(witness_ids.size()); - for(const auto& witness : witness_ids) - { - const auto& witness_obj = witness.as(2); - result.votes_for_witnesses.emplace_back( votes_info_object{ witness_obj.vote_id, witness_obj.id.instance() } ); + + if(!witness_ids.empty()) { + vector< votes_info_object > votes_for_witnesses; + votes_for_witnesses.reserve(witness_ids.size()); + for (const auto &witness : witness_ids) { + const auto &witness_obj = witness.as(2); + votes_for_witnesses.emplace_back(votes_info_object{witness_obj.vote_id, witness_obj.id.instance()}); + } + result.votes_for_witnesses = std::move(votes_for_witnesses); } - 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(2); - result.votes_for_workers.emplace_back( votes_info_object{ for_worker_obj.vote_for, for_worker_obj.id.instance() } ); + + if(!for_worker_ids.empty()) { + vector< votes_info_object > 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(2); + votes_for_workers.emplace_back(votes_info_object{for_worker_obj.vote_for, for_worker_obj.id.instance()}); + } + result.votes_for_workers = std::move(votes_for_workers); } - 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(2); - result.votes_against_workers.emplace_back( votes_info_object{ against_worker_obj.vote_against, against_worker_obj.id.instance() } ); + + if(!against_worker_ids.empty()) { + vector< votes_info_object > 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(2); + votes_against_workers.emplace_back(votes_info_object{against_worker_obj.vote_against, against_worker_obj.id.instance()}); + } + result.votes_against_workers = std::move(votes_against_workers); } - result.votes_for_sons.reserve(son_ids.size()); - for(const auto& son : son_ids) - { - const auto& son_obj = son.as(6); - result.votes_for_sons.emplace_back( votes_info_object{ son_obj.vote_id, son_obj.id.instance() } ); + + if(!son_ids.empty()) { + vector< votes_info_object > votes_for_sons; + votes_for_sons.reserve(son_ids.size()); + for (const auto &son : son_ids) { + const auto &son_obj = son.as(6); + votes_for_sons.emplace_back(votes_info_object{son_obj.vote_id, son_obj.id.instance()}); + } + result.votes_for_sons = std::move(votes_for_sons); } return result; @@ -2266,53 +2290,70 @@ voters_info database_api_impl::get_voters(const string &account_name_or_id) cons //! 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_object = get_worker_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); - result.voters_for_committee_member.vote_id = committee_member_object->vote_id; - result.voters_for_committee_member.voters.reserve(committee_member_voters.size()); + 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) { - result.voters_for_committee_member.voters.emplace_back(voter.get_id()); + 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); - result.voters_for_witness.vote_id = witness_object->vote_id; - result.voters_for_witness.voters.reserve(witness_voters.size()); + 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) { - result.voters_for_witness.voters.emplace_back(voter.get_id()); + voters_for_witness.voters.emplace_back(voter.get_id()); } + result.voters_for_witness = std::move(voters_for_witness); } //! Info for worker voters - if(worker_object) { - const auto& for_worker_voters = get_voters_by_id(worker_object->vote_for); - result.voters_for_worker.vote_id = worker_object->vote_for; - result.voters_for_worker.voters.reserve(for_worker_voters.size()); - for(const auto& voter: for_worker_voters) { - result.voters_for_worker.voters.emplace_back(voter.get_id()); - } - const auto& against_worker_voters = get_voters_by_id(worker_object->vote_against); - result.voters_against_worker.vote_id = worker_object->vote_against; - result.voters_against_worker.voters.reserve(against_worker_voters.size()); - for(const auto& voter: against_worker_voters) { - result.voters_against_worker.voters.emplace_back(voter.get_id()); + if(!worker_objects.empty()) { + vector voters_for_workers(worker_objects.size()); + vector 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); - result.voters_for_son.vote_id = son_object->vote_id; - result.voters_for_son.voters.reserve(son_voters.size()); + 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) { - result.voters_for_son.voters.emplace_back(voter.get_id()); + voters_for_son.voters.emplace_back(voter.get_id()); } + result.voters_for_son = std::move(voters_for_son); } return result; diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 9bac1a3b..7b7de4fa 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -730,7 +730,7 @@ public: * @param account_id_or_name The ID or name of the account whose worker should be retrieved * @return The worker object or null if the account does not have a worker */ - fc::optional get_worker_by_account(const std::string account_id_or_name) const; + vector get_workers_by_account(const std::string account_id_or_name) const; /** * @brief Get names and IDs for registered workers @@ -1135,7 +1135,7 @@ FC_API(graphene::app::database_api, // Workers (get_workers) - (get_worker_by_account) + (get_workers_by_account) (lookup_worker_accounts) (get_worker_count) diff --git a/libraries/chain/include/graphene/chain/voters_info.hpp b/libraries/chain/include/graphene/chain/voters_info.hpp index 5bd09a11..53b0e74a 100644 --- a/libraries/chain/include/graphene/chain/voters_info.hpp +++ b/libraries/chain/include/graphene/chain/voters_info.hpp @@ -19,11 +19,11 @@ namespace graphene { namespace chain { * @ingroup object */ struct voters_info { - voters_info_object voters_for_committee_member; - voters_info_object voters_for_witness; - voters_info_object voters_for_worker; - voters_info_object voters_against_worker; - voters_info_object voters_for_son; + optional voters_for_committee_member; + optional voters_for_witness; + optional > voters_for_workers; + optional > voters_against_workers; + optional voters_for_son; }; } } // graphene::chain @@ -35,6 +35,6 @@ FC_REFLECT( graphene::chain::voters_info_object, FC_REFLECT( graphene::chain::voters_info, (voters_for_committee_member) (voters_for_witness) - (voters_for_worker) - (voters_against_worker) + (voters_for_workers) + (voters_against_workers) (voters_for_son) ) \ No newline at end of file diff --git a/libraries/chain/include/graphene/chain/votes_info.hpp b/libraries/chain/include/graphene/chain/votes_info.hpp index bb757f90..b802a020 100644 --- a/libraries/chain/include/graphene/chain/votes_info.hpp +++ b/libraries/chain/include/graphene/chain/votes_info.hpp @@ -27,11 +27,11 @@ namespace graphene { namespace chain { * @ingroup object */ struct votes_info { - vector< votes_info_object > votes_for_committee_members; - vector< votes_info_object > votes_for_witnesses; - vector< votes_info_object > votes_for_workers; - vector< votes_info_object > votes_against_workers; - vector< votes_info_object > votes_for_sons; + optional< vector< votes_info_object > > votes_for_committee_members; + optional< vector< votes_info_object > > votes_for_witnesses; + optional< vector< votes_info_object > > votes_for_workers; + optional< vector< votes_info_object > > votes_against_workers; + optional< vector< votes_info_object > > votes_for_sons; }; } } // graphene::chain diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index b6cf2644..b2dba7b4 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -249,19 +249,22 @@ BOOST_AUTO_TEST_CASE( son_voting ) //! Check son1account voters auto voters_for_son1account = con.wallet_api_ptr->get_voters("son1account"); - 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()); + 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_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()); + 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_CHECK_EQUAL(nathan_votes.votes_for_sons.size(), 2); - BOOST_CHECK_EQUAL((uint32_t)nathan_votes.votes_for_sons[0].id.instance, son1_obj.id.instance()); - BOOST_CHECK_EQUAL((uint32_t)nathan_votes.votes_for_sons[1].id.instance, son2_obj.id.instance()); + 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"); @@ -275,12 +278,14 @@ BOOST_AUTO_TEST_CASE( son_voting ) //! Check son1account voters voters_for_son1account = con.wallet_api_ptr->get_voters("son1account"); - BOOST_CHECK_EQUAL(voters_for_son1account.voters_for_son.voters.size(), 0); + 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_CHECK_EQUAL(nathan_votes.votes_for_sons.size(), 1); - BOOST_CHECK_EQUAL((uint32_t)nathan_votes.votes_for_sons[0].id.instance, son2_obj.id.instance()); + 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"); @@ -294,11 +299,12 @@ BOOST_AUTO_TEST_CASE( son_voting ) //! Check son2account voters voters_for_son2account = con.wallet_api_ptr->get_voters("son2account"); - BOOST_CHECK_EQUAL(voters_for_son2account.voters_for_son.voters.size(), 0); + 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_EQUAL(nathan_votes.votes_for_sons.size(), 0); + BOOST_CHECK(!nathan_votes.votes_for_sons.valid()); } catch( fc::exception& e ) { BOOST_TEST_MESSAGE("SON cli wallet tests exception"); diff --git a/tests/tests/voting_tests.cpp b/tests/tests/voting_tests.cpp index 7ed8e2a9..2003534a 100644 --- a/tests/tests/voting_tests.cpp +++ b/tests/tests/voting_tests.cpp @@ -324,13 +324,15 @@ BOOST_AUTO_TEST_CASE(track_votes_witnesses_enabled) //! Check witness1 voters const auto voters_for_witness1 = db_api1.get_voters("witness1"); - 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); + 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_CHECK_EQUAL(account_votes.votes_for_witnesses.size(), 1); - BOOST_CHECK_EQUAL((uint32_t)account_votes.votes_for_witnesses[0].id.instance, witness1_object->id.instance()); + 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() } @@ -513,12 +515,14 @@ BOOST_AUTO_TEST_CASE(track_votes_committee_enabled) //! Check committee1 voters const auto voters_for_committee1 = db_api1.get_voters("committee1"); - 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); + 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_CHECK_EQUAL((uint32_t)account_votes.votes_for_committee_members.back().id.instance, committee1_object->id.instance()); + 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() }