diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 8e4dbcb1..16fbba99 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -2057,61 +2057,69 @@ voters_info database_api::get_voters(const string &account_name_or_id) const { vector database_api_impl::lookup_vote_ids(const vector &votes) const { FC_ASSERT(votes.size() < 1000, "Only 1000 votes can be queried at a time"); - //const auto &witness_idx = _db.get_index_type().indices().get(); - //const auto &committee_idx = _db.get_index_type().indices().get(); - //const auto &for_worker_idx = _db.get_index_type().indices().get(); - //const auto &against_worker_idx = _db.get_index_type().indices().get(); - //const auto &son_idx = _db.get_index_type().indices().get(); + const auto &witness_idx = _db.get_index_type().indices().get(); + const auto &committee_idx = _db.get_index_type().indices().get(); + const auto &for_worker_idx = _db.get_index_type().indices().get(); + const auto &against_worker_idx = _db.get_index_type().indices().get(); + const auto &son_bictoin_idx = _db.get_index_type().indices().get(); + const auto &son_hive_idx = _db.get_index_type().indices().get(); vector result; - //result.reserve(votes.size()); - //for (auto id : votes) { - // switch (id.type()) { - // case vote_id_type::committee: { - // auto itr = committee_idx.find(id); - // if (itr != committee_idx.end()) - // result.emplace_back(variant(*itr, 1)); - // else - // result.emplace_back(variant()); - // break; - // } - // case vote_id_type::witness: { - // auto itr = witness_idx.find(id); - // if (itr != witness_idx.end()) - // result.emplace_back(variant(*itr, 1)); - // else - // result.emplace_back(variant()); - // break; - // } - // case vote_id_type::worker: { - // auto itr = for_worker_idx.find(id); - // if (itr != for_worker_idx.end()) { - // result.emplace_back(variant(*itr, 1)); - // } else { - // auto itr = against_worker_idx.find(id); - // if (itr != against_worker_idx.end()) { - // result.emplace_back(variant(*itr, 1)); - // } else { - // result.emplace_back(variant()); - // } - // } - // break; - // } - // case vote_id_type::son: { - // auto itr = son_idx.find(id); - // if (itr != son_idx.end()) - // result.emplace_back(variant(*itr, 5)); - // else - // result.emplace_back(variant()); - // break; - // } - // - // case vote_id_type::VOTE_TYPE_COUNT: - // break; // supress unused enum value warnings - // default: - // FC_CAPTURE_AND_THROW(fc::out_of_range_exception, (id)); - // } - //} + result.reserve(votes.size()); + for (auto id : votes) { + switch (id.type()) { + case vote_id_type::committee: { + auto itr = committee_idx.find(id); + if (itr != committee_idx.end()) + result.emplace_back(variant(*itr, 1)); + else + result.emplace_back(variant()); + break; + } + case vote_id_type::witness: { + auto itr = witness_idx.find(id); + if (itr != witness_idx.end()) + result.emplace_back(variant(*itr, 1)); + else + result.emplace_back(variant()); + break; + } + case vote_id_type::worker: { + auto itr = for_worker_idx.find(id); + if (itr != for_worker_idx.end()) { + result.emplace_back(variant(*itr, 1)); + } else { + auto itr = against_worker_idx.find(id); + if (itr != against_worker_idx.end()) { + result.emplace_back(variant(*itr, 1)); + } else { + result.emplace_back(variant()); + } + } + break; + } + case vote_id_type::son_bitcoin: { + auto itr = son_bictoin_idx.find(id); + if (itr != son_bictoin_idx.end()) + result.emplace_back(variant(*itr, 5)); + else + result.emplace_back(variant()); + break; + } + case vote_id_type::son_hive: { + auto itr = son_hive_idx.find(id); + if (itr != son_hive_idx.end()) + result.emplace_back(variant(*itr, 5)); + else + result.emplace_back(variant()); + break; + } + case vote_id_type::VOTE_TYPE_COUNT: + break; // supress unused enum value warnings + default: + FC_CAPTURE_AND_THROW(fc::out_of_range_exception, (id)); + } + } return result; } diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 3f07317e..d4b55bc5 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1775,6 +1775,8 @@ class wallet_api * @param sons_to_reject the names or ids of the SONs owner accounts you wish * to reject (these will be removed from the list of SONs * you currently approve). This list can be empty. + * @param sidechain the name of the sidechain + * * @param desired_number_of_sons the number of SONs you believe the network * should have. You must vote for at least this many * SONs. You can set this to 0 to abstain from @@ -1785,6 +1787,7 @@ class wallet_api signed_transaction update_son_votes(string voting_account, std::vector sons_to_approve, std::vector sons_to_reject, + sidechain_type sidechain, uint16_t desired_number_of_sons, bool broadcast = false); diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 3002090e..7f22accd 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -2799,47 +2799,70 @@ public: signed_transaction update_son_votes(string voting_account, std::vector sons_to_approve, std::vector sons_to_reject, + sidechain_type sidechain, uint16_t desired_number_of_sons, bool broadcast /* = false */) { try { - //FC_ASSERT(sons_to_approve.size() || sons_to_reject.size(), "Both accepted and rejected lists can't be empty simultaneously"); - //std::vector vbo_info = get_vesting_balances(voting_account); - //std::vector::iterator vbo_iter; - //vbo_iter = std::find_if(vbo_info.begin(), vbo_info.end(), [](vesting_balance_object_with_info const& obj){return obj.balance_type == vesting_balance_type::gpos;}); - //if( vbo_info.size() == 0 || vbo_iter == vbo_info.end()) - // FC_THROW("Account ${account} has no core Token ${TOKEN} vested and will not be allowed to vote for the SON account", ("account", voting_account)("TOKEN", GRAPHENE_SYMBOL)); - // - //account_object voting_account_object = get_account(voting_account); - //for (const std::string& son : sons_to_approve) - //{ - // account_id_type son_owner_account_id = get_account_id(son); - // fc::optional 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); - // if (!insert_result.second) - // FC_THROW("Account ${account} was already voting for SON ${son}", ("account", voting_account)("son", son)); - //} - //for (const std::string& son : sons_to_reject) - //{ - // account_id_type son_owner_account_id = get_account_id(son); - // fc::optional 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); - // if (!votes_removed) - // FC_THROW("Account ${account} is already not voting for SON ${son}", ("account", voting_account)("son", son)); - //} - //voting_account_object.options.num_son = desired_number_of_sons; - // - //account_update_operation account_update_op; - //account_update_op.account = voting_account_object.id; - //account_update_op.new_options = voting_account_object.options; + FC_ASSERT(sons_to_approve.size() || sons_to_reject.size(), "Both accepted and rejected lists can't be empty simultaneously"); + std::vector vbo_info = get_vesting_balances(voting_account); + std::vector::iterator vbo_iter; + vbo_iter = std::find_if(vbo_info.begin(), vbo_info.end(), [](vesting_balance_object_with_info const& obj){return obj.balance_type == vesting_balance_type::gpos;}); + if( vbo_info.size() == 0 || vbo_iter == vbo_info.end()) + FC_THROW("Account ${account} has no core Token ${TOKEN} vested and will not be allowed to vote for the SON account", ("account", voting_account)("TOKEN", GRAPHENE_SYMBOL)); + + account_object voting_account_object = get_account(voting_account); + for (const std::string& son : sons_to_approve) + { + account_id_type son_owner_account_id = get_account_id(son); + fc::optional 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)); + vote_id_type sidechain_vote_id; + switch (sidechain) { + case sidechain_type::bitcoin: + sidechain_vote_id = son_obj->vote_id_bitcoin; + break; + case sidechain_type::hive: + sidechain_vote_id = son_obj->vote_id_hive; + break; + default: + FC_THROW("Invalid sidechain type"); + }; + auto insert_result = voting_account_object.options.votes.insert(sidechain_vote_id); + if (!insert_result.second) + FC_THROW("Account ${account} was already voting for SON ${son}", ("account", voting_account)("son", son)); + } + for (const std::string& son : sons_to_reject) + { + account_id_type son_owner_account_id = get_account_id(son); + fc::optional 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)); + vote_id_type sidechain_vote_id; + switch (sidechain) { + case sidechain_type::bitcoin: + sidechain_vote_id = son_obj->vote_id_bitcoin; + break; + case sidechain_type::hive: + sidechain_vote_id = son_obj->vote_id_hive; + break; + default: + FC_THROW("Invalid sidechain type"); + }; + unsigned votes_removed = voting_account_object.options.votes.erase(sidechain_vote_id); + if (!votes_removed) + FC_THROW("Account ${account} is already not voting for SON ${son}", ("account", voting_account)("son", son)); + } + voting_account_object.options.num_son = desired_number_of_sons; + + account_update_operation account_update_op; + account_update_op.account = voting_account_object.id; + account_update_op.new_options = voting_account_object.options; signed_transaction tx; - //tx.operations.push_back( account_update_op ); - //set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); - //tx.validate(); + tx.operations.push_back( account_update_op ); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + tx.validate(); return sign_transaction( tx, broadcast ); } FC_CAPTURE_AND_RETHROW( (voting_account)(sons_to_approve)(sons_to_reject)(desired_number_of_sons)(broadcast) ) } @@ -5425,10 +5448,11 @@ signed_transaction wallet_api::vote_for_son(string voting_account, signed_transaction wallet_api::update_son_votes(string voting_account, std::vector sons_to_approve, std::vector sons_to_reject, + sidechain_type sidechain, uint16_t desired_number_of_sons, bool broadcast /* = false */) { - return my->update_son_votes(voting_account, sons_to_approve, sons_to_reject, desired_number_of_sons, broadcast); + return my->update_son_votes(voting_account, sons_to_approve, sons_to_reject, sidechain, desired_number_of_sons, broadcast); } signed_transaction wallet_api::sidechain_deposit_transaction( const string &son_name_or_id, diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 8e609f45..03c33bb9 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -506,8 +506,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) accepted.push_back("son1account"); accepted.push_back("son2account"); con.wallet_api_ptr->create_vesting_balance("nathan", "1000", "1.3.0", vesting_balance_type::gpos, true); - update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, - rejected, 2, true); + update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::bitcoin, 2, true); generate_block(); BOOST_CHECK(generate_maintenance_block()); @@ -527,8 +527,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) rejected.clear(); rejected.push_back("son1account"); con.wallet_api_ptr->create_vesting_balance("nathan", "1000", "1.3.0", vesting_balance_type::gpos, true); - update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, - rejected, 1, true); + update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::bitcoin, 1, true); BOOST_CHECK(generate_maintenance_block()); // Verify the votes @@ -546,8 +546,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) accepted.clear(); rejected.clear(); rejected.push_back("son1accnt"); - BOOST_CHECK_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, - rejected, 1, true), fc::exception); + BOOST_CHECK_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::bitcoin, 1, true), fc::exception); generate_block(); // Verify the votes @@ -564,8 +564,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) accepted.clear(); rejected.clear(); rejected.push_back("son2account"); - update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, - rejected, 0, true); + update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::bitcoin, 0, true); BOOST_CHECK(generate_maintenance_block()); // Verify the votes @@ -583,8 +583,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) rejected.clear(); rejected.push_back("son1accnt"); accepted.push_back("son1accnt"); - BOOST_REQUIRE_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, - rejected, 1, true), fc::exception); + BOOST_REQUIRE_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::bitcoin, 1, true), fc::exception); BOOST_CHECK(generate_maintenance_block()); // Verify the votes @@ -600,8 +600,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test ) // Try to accept and reject empty lists accepted.clear(); rejected.clear(); - BOOST_REQUIRE_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, - rejected, 1, true), fc::exception); + BOOST_REQUIRE_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted, rejected, + sidechain_type::bitcoin, 1, true), fc::exception); BOOST_CHECK(generate_maintenance_block()); // Verify the votes