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
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.
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.
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.
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.
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 authorityasset_id_type voting_asset
- the asset on which to base the votingunsigned_int num_members
- the number of authority members to vote on if fixed, or 0 otherwiseunsigned_int min_members
- the minimum number of authority members to elect, or 0 if fixedunsigned_int max_members
- the maximum number of authority members that can be elected, or 0 if fixeduint16_t threshold
- the threshold scaled percentage of weighter member approvals required for authority approvalflat_set<account_id_type> candidates
- a list of candidates eligible for voting, or emptyoptional<asset> candidates_hold_min
- an asset and minimum amount of it that candidates must hold to be eligible for votingbool proxy_allowed
- indicates if proxy voting is allowedoptional<time_point_sec> vote_until
- an optional ending date after which voting slates are frozenoptional<uint32_t> retally_interval
- if present, the vote tally result is applied to the authority only everyretally_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 thevoting_allowed
flag set.threshold
must be in the range1..GRAPHENE_100_PERCENT
- If
num_members
is 0 thenmin_members
andmax_members
must both be positive. - If
num_members
is positive then bothmin_members
andmax_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.
- Its size must be greater or equal to
- If
candidates_hold_min
is present thecandidates
must be empty. vote_until
, if present, must be in the futureretally_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
.
Fields:
account_id_type owner
- the account to pay the fee, must have created the authorityelected_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 toowner
. - 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.
Fields:
account_id_type voter
- the voting account, also pays feeelected_authority_id_type authority
- the authority on which to voteunsigned_int number
- the number of members the authority should have, or 0 if it is fixedflat_set<account_id_type> votes_to_add
- a list of accounts to add to the current voting slateflat_set<account_id_type> votes_to_remove
- a list of accounts to remove from the current voting slateoptional<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
thennumber
must equal 0. - If
authority.num_members == 0
thenauthority.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
- must be present in the user's voting slate on
- If both
votes_to_add
andvotes_to_remove
are empty thennumber
must be different than thevoter
's previous choice fornumber
, or thevoter
's proxy setting must change. - If
proxy
is present thenauthority.proxy_allowed
must betrue
.proxy
account must exist and must have a voting slate for theauthority
.number
must equal 0 and bothvotes_to_add
andvotes_to_remove
must be empty.
Evaluation:
- If
proxy
is not present butvoter
had set a proxy on thisauthority
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.
- Subtract the
- If
proxy
is present andvoter
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 toproxy
's proxy token count and adjust vote tally accordingly.
- If
proxy
is present andvoter
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 setvotes_to_add
,votes_to_remove
andnumber
are applied to the user's voting slate.- Let
voting_balance
be the sum of thevoter
'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 newnumber
, the negativevoting_balance
for each vote to be removed and the previousnumber
. - 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 respectiveauthority
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.
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.
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.
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)
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).
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.
- 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.
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.
This document is placed in the public domain.