diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 4d109171..0ac0b88a 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1349,6 +1349,38 @@ class wallet_api bool approve, bool broadcast = false); + /** Change your witness votes. + * + * An account can publish a list of all witnesses they approve of. + * Each account's vote is weighted according to the number of shares of the + * core asset owned by that account at the time the votes are tallied. + * This command allows you to add or remove one or more witnesses from this list + * in one call. When you are changing your vote on several witnesses, this + * may be easier than multiple `vote_for_witness` and + * `set_desired_witness_and_committee_member_count` calls. + * + * @note you cannot vote against a witness, you can only vote for the witness + * or not vote for the witness. + * + * @param voting_account the name or id of the account who is voting with their shares + * @param witnesses_to_approve the names or ids of the witnesses owner accounts you wish + * to approve (these will be added to the list of witnesses + * you currently approve). This list can be empty. + * @param witnesses_to_reject the names or ids of the witnesses owner accounts you wish + * to reject (these will be removed fromthe list of witnesses + * you currently approve). This list can be empty. + * @param desired_number_of_witnesses the number of witnesses you believe the network + * should have. You must vote for at least this many + * witnesses. You can set this to 0 to abstain from + * voting on the number of witnesses. + * @param broadcast true if you wish to broadcast the transaction + * @return the signed transaction changing your vote for the given witnesses + */ + signed_transaction update_witness_votes(string voting_account, + std::vector witnesses_to_approve, + std::vector witnesses_to_reject, + uint16_t desired_number_of_witnesses, + bool broadcast = false); /** Set the voting proxy for an account. * * If a user does not wish to take an active part in voting, they can choose @@ -1700,6 +1732,7 @@ FC_API( graphene::wallet::wallet_api, (withdraw_vesting) (vote_for_committee_member) (vote_for_witness) + (update_witness_votes) (set_voting_proxy) (set_desired_witness_and_committee_member_count) (get_account) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index e2c78e54..8f24192a 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -2018,9 +2018,9 @@ public: } FC_CAPTURE_AND_RETHROW( (voting_account)(committee_member)(approve)(broadcast) ) } signed_transaction vote_for_witness(string voting_account, - string witness, - bool approve, - bool broadcast /* = false */) + string witness, + bool approve, + bool broadcast /* = false */) { try { account_object voting_account_object = get_account(voting_account); account_id_type witness_owner_account_id = get_account_id(witness); @@ -2051,6 +2051,47 @@ public: return sign_transaction( tx, broadcast ); } FC_CAPTURE_AND_RETHROW( (voting_account)(witness)(approve)(broadcast) ) } + signed_transaction update_witness_votes(string voting_account, + std::vector witnesses_to_approve, + std::vector witnesses_to_reject, + uint16_t desired_number_of_witnesses, + bool broadcast /* = false */) + { try { + account_object voting_account_object = get_account(voting_account); + for (const std::string& witness : witnesses_to_approve) + { + account_id_type witness_owner_account_id = get_account_id(witness); + fc::optional witness_obj = _remote_db->get_witness_by_account(witness_owner_account_id); + if (!witness_obj) + FC_THROW("Account ${witness} is not registered as a witness", ("witness", witness)); + auto insert_result = voting_account_object.options.votes.insert(witness_obj->vote_id); + if (!insert_result.second) + FC_THROW("Account ${account} was already voting for witness ${witness}", ("account", voting_account)("witness", witness)); + } + for (const std::string& witness : witnesses_to_reject) + { + account_id_type witness_owner_account_id = get_account_id(witness); + fc::optional witness_obj = _remote_db->get_witness_by_account(witness_owner_account_id); + if (!witness_obj) + FC_THROW("Account ${witness} is not registered as a witness", ("witness", witness)); + unsigned votes_removed = voting_account_object.options.votes.erase(witness_obj->vote_id); + if (!votes_removed) + FC_THROW("Account ${account} is already not voting for witness ${witness}", ("account", voting_account)("witness", witness)); + } + voting_account_object.options.num_witness = desired_number_of_witnesses; + + 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(); + + return sign_transaction( tx, broadcast ); + } FC_CAPTURE_AND_RETHROW( (voting_account)(witnesses_to_approve)(witnesses_to_reject)(desired_number_of_witnesses)(broadcast) ) } + signed_transaction set_voting_proxy(string account_to_modify, optional voting_account, bool broadcast /* = false */) @@ -3870,6 +3911,15 @@ signed_transaction wallet_api::vote_for_witness(string voting_account, return my->vote_for_witness(voting_account, witness, approve, broadcast); } +signed_transaction wallet_api::update_witness_votes(string voting_account, + std::vector witnesses_to_approve, + std::vector witnesses_to_reject, + uint16_t desired_number_of_witnesses, + bool broadcast /* = false */) +{ + return my->update_witness_votes(voting_account, witnesses_to_approve, witnesses_to_reject, desired_number_of_witnesses, broadcast); +} + signed_transaction wallet_api::set_voting_proxy(string account_to_modify, optional voting_account, bool broadcast /* = false */)