bigchaindb/bigchaindb/upsert_validator/validator_election.py
Zachary Bowen 0fe749d830 Create abstract election class (#2498).
* Problem: `ValidatorElection` and `MigrationElection` need to inherit from a common `Election` class.

Solution: Factored the common logic out of `ValidatorElection` and moved it to `Election` parent class.

* Problem: No need to store different types of elections in their own tables

Solution: Remove `DB_TABLE` property from `Election` class.

Solution: Created the `elections` table with secondary_index `election_id`.

* Problem: `UpsertValidatorVote` can be generalized to just be `Vote`

Solution: Renamed, refactored and moved the `Vote` class to tie in with the more general `Election` base class.

* Problem: `election_id` is not unique if two elections have the same properties.

Solution: Added a random `uuid4` seed to enforce uniqueness.
2018-09-11 15:39:46 +02:00

50 lines
2.1 KiB
Python

# Copyright BigchainDB GmbH and BigchainDB contributors
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
# Code is Apache-2.0 and docs are CC-BY-4.0
from bigchaindb.common.exceptions import InvalidPowerChange
from bigchaindb.elections.election import Election
from bigchaindb.common.schema import (TX_SCHEMA_VALIDATOR_ELECTION)
from .validator_utils import (new_validator_set, encode_validator, validate_asset_public_key)
class ValidatorElection(Election):
OPERATION = 'VALIDATOR_ELECTION'
# NOTE: this transaction class extends create so the operation inheritence is achieved
# by renaming CREATE to VALIDATOR_ELECTION
CREATE = OPERATION
ALLOWED_OPERATIONS = (OPERATION,)
TX_SCHEMA_CUSTOM = TX_SCHEMA_VALIDATOR_ELECTION
def validate(self, bigchain, current_transactions=[]):
"""For more details refer BEP-21: https://github.com/bigchaindb/BEPs/tree/master/21
"""
current_validators = self.get_validators(bigchain)
super(ValidatorElection, self).validate(bigchain, current_transactions=current_transactions)
# NOTE: change more than 1/3 of the current power is not allowed
if self.asset['data']['power'] >= (1/3)*sum(current_validators.values()):
raise InvalidPowerChange('`power` change must be less than 1/3 of total power')
return self
@classmethod
def validate_schema(cls, tx):
super(ValidatorElection, cls).validate_schema(tx)
validate_asset_public_key(tx['asset']['data']['public_key'])
@classmethod
def on_approval(cls, bigchain, election, new_height):
# The new validator set comes into effect from height = new_height+1
validator_updates = [election.asset['data']]
curr_validator_set = bigchain.get_validators(new_height)
updated_validator_set = new_validator_set(curr_validator_set,
validator_updates)
updated_validator_set = [v for v in updated_validator_set if v['voting_power'] > 0]
bigchain.store_validator_set(new_height+1, updated_validator_set)
return encode_validator(election.asset['data'])