Skip to content

Latest commit

 

History

History
225 lines (145 loc) · 13 KB

bsip-0084.md

File metadata and controls

225 lines (145 loc) · 13 KB
BSIP: 0084
Title: Elections based on non-core asset
Authors: Peter Conrad
Status: Draft
Type: Protocol
Created: 2019-10-12
Discussion: https://github.com/bitshares/bsips/issues/81

Abstract

From the beginning, the BitShares blockchain has offered the ability to vote with the core token, and to have elected accounts govern the blockchain.

For specific use-cases it can be desirable to have a similar mechanism for voting and elections where the votes are counted in relation not to BTS but to some other asset. An example might be a community of people who are interested in a specific topic.

This BSIP proposes changes that will enable elections based on dedicated assets.

Motivation

The feature has been requested from independent businesses as well as from within the community.

It allows the definition of more fine-grained roles in any kind of governance, and offers the possibility to elect people with the specific knowledge required for specific tasks.

Rationale

There are fundamental differences between the mechanics proposed here and the mechanics already in place for BTS-based voting.

BTS balances are affected by almost every operation, due to transaction fees. The voting tokens will only be affected when they are being used.

BTS is used in a multitude of ways, e. g. as collateral, as the counterpart in most active markets, as payment for workers and witnesses, as cashback for fees and so on. Contrarily, it is assumed that the primary purpose of the voting tokens will be voting. They are unlikely to be used as collateral.

These differences allow for various simplifications and optimizations. In particular, we propose to allow only liquid balances for voting. Because these presumably change rarely in comparison to the number of distinct balances, it is more efficient to recalculate votes on the fly instead of once per maintenance interval (see STEEM for comparison). Nevertheless, the Elected Authority can be configured that the actual accounts that are in control of the Authority only change every given time interval (e.g. only every hour).

Furthermore, we make no distinction between voting and elections. Voting (as in making a yes/no decision) can be emulated with an election where only the votes for two designated candidates are counted and compared to each other. Depending on voting rules (to be defined externally on a case-by-case basis), the one with more votes wins, or perhaps the one with an absolute majority of eligible votes.

Because maintaining elected authorities is expensive (in terms of node resources), they should not stay active any longer than necessary. We propose to incentivize removal of elected authorities by locking up half of the creation fee, and to pay it back to the creator when the object is deleted. It is recommended that the committee set an accordingly high fee for the create operation.

Specifications

1. New asset flag "voting_allowed"

A new asset flag/permission "voting_allowed" will be introduced. At the time of the hardfork, all existing assets except BTS will have the corresponding permission set.

As usual with flags, the flag can be changed only if the permission is set. The permission can be unset any time, but can be set only when supply is zero.

The flag must not be used before the time of the hardfork.

2. New operation "elected_authority_create"

Note 1: Since the overall computational overhead for this voting mechanism is significant, the height of the fee should reflect this.

Note 2: The new asset flag voting_allowed is only checked for this operation. If the flag is removed from an asset, any existing elected authorities are unaffected.

Fields:

  • account_id_type creator - the account to pay the fee, also the only one who can delete the authority
  • asset_id_type voting_asset - the asset on which to base the voting
  • unsigned_int num_members - the number of authority members to vote on if fixed, or 0 otherwise
  • unsigned_int min_members - the minimum number of authority members to elect, or 0 if fixed
  • unsigned_int max_members - the maximum number of authority members that can be elected, or 0 if fixed
  • uint16_t threshold - the threshold scaled percentage of weighter member approvals required for authority approval
  • flat_set<account_id_type> candidates - a list of candidates eligible for voting, or empty
  • optional<asset> candidates_hold_min - an asset and minimum amount of it that candidates must hold to be eligible for voting
  • bool proxy_allowed - indicates if proxy voting is allowed
  • optional<time_point_sec> vote_until - an optional ending date after which voting slates are frozen
  • optional<uint32_t> retally_interval - if present, the vote tally result is applied to the authority only every retally_interval seconds

Validation:

The operation must not be used before the time of the hardfork.

  • creator must exist, must have lifetime membership, and must have sufficient balance to pay the fee.
  • voting_asset must exist and must have the voting_allowed flag set.
  • threshold must be in the range 1..GRAPHENE_100_PERCENT
  • If num_members is 0 then min_members and max_members must both be positive.
  • If num_members is positive then both min_members and max_members must equal 0.
  • If candidates is not empty then
    • Its size must be greater or equal to max(num_members,min_members).
    • candidates_hold_min must not be present.
  • If candidates_hold_min is present the candidates must be empty.
  • vote_until, if present, must be in the future
  • retally_interval, if present, must be greater than the block time

Evaluation:

A new object type elected_authority_object is introduced. The operation creates such an object using the fields from the operation.

A new, empty authority is created. The desired number of members for the authority is set to max(num_members,min_members).

Half of the operation fee is set aside and stored in the elected_authority_object.

3. New operation "elected_authority_delete"

Fields:

  • account_id_type owner - the account to pay the fee, must have created the authority
  • elected_authority_id_type authority - the authority to delete

Validation:

The operation must not be used before the time of the hardfork.

  • authority must exist.
  • owner == authority.creator

Evaluation:

  • The fee stored in authority is returned to owner.
  • The elected_authority_object is deleted.
  • All related objects, including the authority as well as all user votes, are also deleted.

Note: Afterwards, accounts that have the authority still referenced in its owner authority will be unable to ever change their owner again. Accounts that have the authority referenced in their active authority will be usable only by their owner authority until the active authority has been changed.

4. New operation "elected_authority_vote"

Fields:

  • account_id_type voter - the voting account, also pays fee
  • elected_authority_id_type authority - the authority on which to vote
  • unsigned_int number - the number of members the authority should have, or 0 if it is fixed
  • flat_set<account_id_type> votes_to_add - a list of accounts to add to the current voting slate
  • flat_set<account_id_type> votes_to_remove - a list of accounts to remove from the current voting slate
  • optional<account_id_type> proxy - an optional voting proxy

Validation:

The operation must not be used before the time of the hardfork.

  • authority must exist.
  • voter must exist and have sufficient balance to pay the fee.
  • If authority.vote_until is present, then it must be in the future.
  • If authority.num_members > 0 then number must equal 0.
  • If authority.num_members == 0 then authority.min_members <= number <= authority.max_members.
  • For all entries in votes_to_add:
    • must exist
    • must not be present in the user's voting slate on authority
    • if authority.candidates is not empty then it must be contained therein
    • if authority.candidates_hold_min is present then it must own at least the given amount of tokens of the given type
  • For all entries in votes_to_remove:
    • must be present in the user's voting slate on authority
  • If both votes_to_add and votes_to_remove are empty then number must be different than the voter's previous choice for number, or the voter's proxy setting must change.
  • If proxy is present then
    • authority.proxy_allowed must be true.
    • proxy account must exist and must have a voting slate for the authority.
    • number must equal 0 and both votes_to_add and votes_to_remove must be empty.

Evaluation:

  • If proxy is not present but voter had set a proxy on this authority before
    • Subtract the voter's token balance from the old proxy's proxy token count and adjust vote tally accordingly.
    • Apply votes_to_add as described below.
  • If proxy is present and voter had not set a proxy before
    • Remove all accounts from the user's own voting slate and adjust vote tally accordingly.
    • Set proxy in voting slate.
    • Add voter's balance to proxy's proxy token count and adjust vote tally accordingly.
  • If proxy is present and voter had set a (different) proxy before
    • Remove old proxy and adjust vote tally accordingly (see above).
    • Set new proxy and adjust vote tally accordingly (see above).
  • If proxy is not set
    • votes_to_add, votes_to_remove and number are applied to the user's voting slate.
    • Let voting_balance be the sum of the voter's token balance of the asset plus his proxy token balance.
    • The voting delta is the voting_balance for each vote to be added and for the new number, the negative voting_balance for each vote to be removed and the previous number.
    • The voting delta in votes is applied to the vote tally of authority.
    • If retally_interval is absent, the resulting differences in the election outcome (if any) are reflected in the respective authority object.

Note: the intent is to have vote tallying work in the same way it is currently performed when voting with BTS. The same goes for determining the number of accounts that make up the authority, unless it is fixed.

5. adjust_balance

The chain logic for adjusting account balances is modified as follows:

  • For each voting slate of the balance's owner with the same asset type as is being updated:
    • If the voting slate points to a proxy, adjust the proxy's proxy token count according to the balance delta.
    • Apply the balance delta to the vote tally according to the user's (or proxy's if set) voting slate.
    • Reflect the resulting differences to the election outcome in the respective authority object.

6. account_update_operation

After the time of the hardfork, a new type of special_authority is allowed. This new type wraps an elected_authority_object.

If the wrapped elected_authority has been deleted, the special_authority will block, i. e. it cannot authorize anything anymore.

Note: for simplicity, it is left to the implementers to decide if account_create_operation is modified accordingly.

7. apply_block

Code is added to database::apply_block to check if any retally_intervals have passed. For each such elected_authority_object,

  • the current vote tally result is applied to the authority
  • the point in time of the next retally is calculated as the next multiple of the retally_interval (the intent is to have the retally happen at predictable "natural" times, e. g. at the full hour, just like the maintenance interval)

Discussion

Deletion

Deleting an authority that is still being used, e. g. as the active authority of an account, can cause problems.

The problem is, if we disallow deletion if the authority is in use anywhere, then it is easy for someone to block an authority from being deleted.

OTOH someone who uses an elected authority that is not under his control can be expected to coordinate this with the authority owner. Setting an elected authority as owner on an account is strongly discouraged, because authority deletion would block the account. Use as an active authority (or feed producer) can easily be repaired by the account owner (or asset owner).

"Locked" balances

As explained in the "Rationale" section we have made certain assumptions about the voting tokens that allow many simplifications when compared to the current BTS-based voting system.

Not all of these assumptions may prove to be true in all cases.

Risks

  • This BSIP has an impact on the performance of balance-changing operations. It is believed that the overall impact will be low, because only few assets will be affected.
  • Deleting an authority that is still being used, e. g. as the active authority of an account, can cause problems.

Summary for Shareholders

This BSIP introduces new operations to allow voting and elections using other assets than BTS. Authorities based on election outcomes can be assigned to accounts. Proxy voting is not possible in these elections.

Copyright

This document is placed in the public domain.