Skip to content

Commit

Permalink
Merge pull request #114 from bitshares/bsip-account_update_votes_oper…
Browse files Browse the repository at this point in the history
…ation

BSIP47 - An explicit voting operation
  • Loading branch information
ryanRfox committed Sep 19, 2019
2 parents a43a61e + 54c598a commit 254fdf6
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Number | Title |
[44](bsip-0044.md) | Hashed Time-Locked Contract | Ryan R. Fox | Protocol | Installed
[45](bsip-0045.md) | Add bitAsset Backing Collateral flag/permission | Customminer | Protocol | Draft
[46](https://github.com/bitshares/bsips/pull/111) | Escrow Concepts | Taconator | Informational | Accepted
[47](https://github.com/bitshares/bsips/pull/114) | An Explicit Voting Operation | Fabian Schuh | Protocol | Draft
[47](bsip-0047.md) | Vote Proxies for Different Referendum Categories and explicit voting operation | Fabian Schuh | Protocol | Draft
[48](https://github.com/bitshares/bsips/pull/115) | Add Flag to Asset to Prevent Manipulating Max Supply | Fabian Schuh | Protocol | Draft
[50](https://github.com/bitshares/bsips/issues/88) | Stealth development, Phase II | Chris Sanborn | Informational | Draft
[51](https://github.com/bitshares/bsips/issues/89) | New operations for Confidential Asset (CA) transactions | Chris Sanborn | Protocol | Draft
Expand Down
230 changes: 230 additions & 0 deletions bsip-0047.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
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](https://github.com/bitshares/bsips/blob/master/bsip-0040.md) 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 &le; `num_committee` &le; size of new committee slate &le; `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 &le; `new_num_committee` &le; size of new committee slate &le; `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 &le; `num_witness` &le; size of new witness slate &le; `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 &le; `new_num_witness` &le; size of new witness slate &le; `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](https://github.com/bitshares/bsips/bsip-0022.md) or by [vote staking](https://github.com/bitshares/bsips/bsip-0024.md), 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](https://github.com/bitshares/bsips/blob/master/bsip-0040.md) 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

- [Vote Proxies for Different Referendum Categories](https://github.com/bitshares/bsips/issues/177)
- [Proposed details for BSIP-22 specifications](https://github.com/bitshares/bsips/pull/153)

0 comments on commit 254fdf6

Please sign in to comment.