Skip to content

Latest commit

 

History

History
230 lines (153 loc) · 12.6 KB

bsip-0047.md

File metadata and controls

230 lines (153 loc) · 12.6 KB
BSIP:       47
Title:      Vote Proxies for Different Referendum Categories and explicit voting operation
Authors:    Fabian Schuh <https://github.com/xeroc>
            Dmitrij Vinokour <https://github.com/Dimfred>
            Alex Megalokonomos <https://github.com/clockworkgr>
            Michel Santos <https://github.com/MichelSantos>
Status:     Draft
Type:       Protocol
Created:    2018-09-20
Discussion: https://github.com/bitshares/bsips/pull/114

Abstract

Voting power by core token holders may be assigned to different proxies in each of the BitShares referendum categories: witnesses, committee members, and worker proposals.

Motivation

Some proxies can be more or less knowledgeable, wise, and trusted by token holders to vote on certain referendum categories than others. It is therefore desirable to empower token holders to select different proxies for each of the referendum categories.

If the ability to select multiple proxies or to directly vote through a single new operation were made possible, this new operation could be used in conjunction with BSIP40 which will allow an account holder to assign a specific key for voting. This combination could simplify voting for many account holders.

Rationale

Holders of the core token of BitShares (BTS) have always had the ability to directly vote on three referendum categories: witnesses, committee members, and worker proposals. They have also had the option of delegating their voting power to another account (a "proxy") to vote on any of these referendum categories.

Rather than delegating voting power to a single proxy for all three referendum categories, a core token holder might prefer to select different proxies for each of the referendum categories.

This more granular approach empowers core token holders with more options. A BTS token holder may choose to directly vote on any referendum category including the option to abstain. A BTS token holder may choose to select proxies for each of the referendum categories. Each of the referendum categories may have distinct proxies or may have common proxies. Some referendum categories may have assigned proxies while others may be unassigned. Any referendum category that does not have an assigned proxy permits the voter to vote directly on any referendum in that category. But if a confused core token holder votes for a referendum in a category while also delegating that category to a proxy, the token holder's direct vote shall be ignored.

The introduction of a new operation (account_update_votes_operation) with additional changes to the core shall also enable an account holder to select proxies for different referendum categories, and to vote for referendums without needing to use the existing account_update_operation. The existing operation requires the account holder to pass all possible account settings to avoid overriding existing settings. This is inconvenient and requires a higher payload to be stored on the blockchain which results in the account holder paying a higher fee. The proposed operation shall only update the portion of the account data that is related to voting and should also reduce the fee.

The new operation only needs to include

  • The voting account
  • The desired proxy, if any, for the committee referendum category
  • The desired proxy, if any, for the witness referendum category
  • The desired proxy, if any, for the worker referendum category
  • The quantity of desired witnesses
  • The quantity of desired committee members
  • The list of referendums that are supported

Specifications

Whenever a proxy for a category is assigned, any direct votes by a core token holder within that category shall be ignored. Whenever a proxy for a category is unassigned, any direct votes by a core token holder for that category shall be counted during the vote tallying process of the blockchain. This shall require an upgrade to the protocol.

GRAPHENE_PROXY_PER_CATEGORY_ACCOUNT (New)

A new special account GRAPHENE_PROXY_PER_CATEGORY_ACCOUNT with ID 1.2.6 is defined and added to the database at protocol change activation time.

account_options extension (Existing)

Fields:

The account_options receives three new extensions:

  • optional<account_id_type> committee_voting_account
  • optional<account_id_type> witness_voting_account
  • optional<account_id_type> worker_voting_account

Validation:

  • These extensions must not be present before the protocol change activation date, neither in transactions nor in proposals.
  • If any extension is present, it must contain the ID of an existing account.
  • If any extension is present, account_options.voting_account == GRAPHENE_PROXY_PER_CATEGORY_ACCOUNT

account_object(Existing)

Note: this is an implementation detail and meant to be a hint for later development. The actual implementation may differ.

The account object shall receive these new fields:

  • flat_set<vote_id_type> committee_votes
  • flat_set<vote_id_type> witness_votes
  • flat_set<vote_id_type> worker_votes

account_create_operation and account_update_operation shall be modified to create these sets by filtering the account_options.votes field appropriately. account_update_votes_operation shall also create these sets by filtering the votes_to_add and votes_to_remove fields appropriately.

account_update_votes_operation (New)

The following is an example implementation.

struct account_update_votes_operation : public base_operation
{
	asset fee;

	/// The account to update
	account_id_type account;

	/// New account options
	flat_set<vote_id_type>    votes_to_add;
	flat_set<vote_id_type>    votes_to_remove;

	// A new voting account to set
	optional<account_id_type> committee_voting_account
	optional<account_id_type> witness_voting_account
	optional<account_id_type> worker_voting_account

	// A new number of witness_votes to set
	optional<uint16_t> num_witness;

	// A new number of committee_votes to set
	optional<uint16_t> num_committee;

	// For future extensions (see account_update_operation)
	extensions_type extensions;
};

Changes to direct votes can be specified by means of a list of vote identifiers to be added or removed. This has multiple advantages:

  • Reduces the size of the operation compared to replacing the entire slate
  • Allows to easily compare votes before and after the operation

Validation checks:

Many of the validation checks are dependent on the merger of the proposed values in the operation with the account's current voting values on the blockchain.

General validation checks

  • account must be a valid account ID, must exist, must authorize the operation, must pay fee
  • committee_voting_account, if present, must be a valid account ID, must exist
  • witness_voting_account, if present, must be a valid account ID, must exist
  • worker_voting_account, if present, must be a valid account ID, must exist
  • Validate the existence of each vote to add and remove

Committee validation checks

  • Let the new committee slate consist of the current commitee slate plus the committee votes_to_add minus the committee votes_to_remove
  • If committee_voting_account is present
    • Let new_committee_account = committee_voting_account
  • otherwise
    • Let new_committee_account = account_options.committee_voting_account
  • num_committee, if present, is only allowed when:
    • new_committee_account = GRAPHENE_PROXY_TO_SELF_ACCOUNT, and
    • 0 ≤ num_committee ≤ size of new committee slate ≤ chain_params.maximum_committee_count
  • If num_committee is present
    • Let new_num_committee = num_committee
  • otherwise
    • Let new_num_committee = account_options.num_committee
  • Non-empty committee votes_to_add and votes_to_remove are only allowed when:
    • new_committee_account = GRAPHENE_PROXY_TO_SELF_ACCOUNT, and
    • 0 ≤ new_num_committee ≤ size of new committee slate ≤ chain_params.maximum_committee_count

Witness Validation Checks

  • Let the new witness slate consist of the current witness slate plus the witness votes_to_add minus the witness votes_to_remove
  • If witness_voting_account is present
    • Let new_witness_account = witness_voting_account
  • otherwise
    • Let new_witness_account = account_options.witness_voting_account
  • num_witness, if present, is only allowed when:
    • if new_witness_account = GRAPHENE_PROXY_TO_SELF_ACCOUNT, and
    • if 0 ≤ num_witness ≤ size of new witness slate ≤ chain_params.maximum_witness_count
  • If num_witness is present
    • Let new_num_witness = num_witness
  • otherwise
    • Let new_num_witness = account_options.num_witness
  • Non-empty witness votes_to_add and votes_to_remove are only allowed when:
    • new_witness_account = GRAPHENE_PROXY_TO_SELF_ACCOUNT, and
    • 0 ≤ new_num_witness ≤ size of new witness slate ≤ chain_params.maximum_witness_count

Worker Validation Checks

  • If worker_voting_account is present
    • Let new_worker_account = worker_voting_account
  • otherwise
    • Let new_worker_account = account_options.worker_voting_account
  • The worker votes_to_add and votes_to_remove are valid:
    • if new_worker_account = GRAPHENE_PROXY_TO_SELF_ACCOUNT

Evaluation:

  • Update the account's account_options.committee_votes, account_options.witness_votes, and account_options.worker_votes by filtering the votes_to_add and votes_to_remove field appropriately
  • If any of committee_voting_account, witness_voting_account or worker_voting_account is present
    • Update the corresponding field in the account's account_options
    • Set the account's account_options.voting_account to GRAPHENE_PROXY_PER_CATEGORY_ACCOUNT
  • if num_witness is present
    • account_options.witness_votes = num_witness
  • if num_committee is present
    • account_options.committee_votes = num_committee
  • Update the account's last vote time to the head block time

account_create_operation (Existing)

This operation shall also be updated for backwards compatibility. If account_options.voting_account == GRAPHENE_PROXY_PER_CATEGORY_ACCOUNT, then the account's per-category voting proxies are set to the specified extension if present, or to GRAPHENE_PROXY_TO_SELF_ACCOUNT if absent. Otherwise, the voting proxy for all three categories is set to account_options.voting_account.

account_update_operation(Existing)

This operation shall also be updated for backwards compatibility. If account_options.voting_account == GRAPHENE_PROXY_PER_CATEGORY_ACCOUNT, then the account's per-category voting proxies are set to the specified extension if present, or remain unchanged if absent. Otherwise, the voting proxy for all three categories is set to account_options.voting_account.

Vote Tallying

The vote tallying algorithm shall be modified to select the opinion_account per voting category, and use the current account's voting stake only for the opinion account's votes in the respective category.

Other BSIPs that may scale the voting weight of an account, such as by vote decay or by vote staking, can remain compatible with this BSIP by assigning the scaled voting weight to the different voting proxies that may or may not be selected by an account.

Discussion

Performance Impact

There will be a performance impact by account_create_operation, account_update_operation, and account_update_votes_operation due to the filtering if implemented as suggested. This impact should be small overall, because these operations are comparatively rare.

There will also be some overhead for vote tallying. Vote tallying happens only during the maintenance interval so the operational impact should be negligible as well.

Note that the cumulative effect of both may be noticable during chain replay.

Summary for Shareholders

This proposal introduces a means for token holders to select different proxies in each of the BitShares referendum categories: witnesses, committee members, and worker proposals. The proposed mechanism in combination with BSIP40 will permit core token holders to simplify automated voting without compromising the account through the use of a new operation that can be used only for voting.

Copyright

This document is placed in the public domain.

See Also