mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Problem: The way end_block checks for concluded elections assumes there is only one type of election (so we can't conclude an upsert-validator and a migration at the same height)
Solution: Re-engineered the code in `Elections` that checks for `approved_elections` to check all election types simultaneously, then return concluded elections sorted by election type
This commit is contained in:
parent
af36843788
commit
7803e6320f
@ -20,13 +20,13 @@ from abci.types_pb2 import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from bigchaindb import BigchainDB
|
from bigchaindb import BigchainDB
|
||||||
|
from bigchaindb.elections.election import Election
|
||||||
from bigchaindb.version import __tm_supported_versions__
|
from bigchaindb.version import __tm_supported_versions__
|
||||||
from bigchaindb.utils import tendermint_version_is_compatible
|
from bigchaindb.utils import tendermint_version_is_compatible
|
||||||
from bigchaindb.tendermint_utils import (decode_transaction,
|
from bigchaindb.tendermint_utils import (decode_transaction,
|
||||||
calculate_hash)
|
calculate_hash)
|
||||||
from bigchaindb.lib import Block, PreCommitState
|
from bigchaindb.lib import Block, PreCommitState
|
||||||
from bigchaindb.backend.query import PRE_COMMIT_ID
|
from bigchaindb.backend.query import PRE_COMMIT_ID
|
||||||
from bigchaindb.upsert_validator import ValidatorElection
|
|
||||||
import bigchaindb.upsert_validator.validator_utils as vutils
|
import bigchaindb.upsert_validator.validator_utils as vutils
|
||||||
from bigchaindb.events import EventTypes, Event
|
from bigchaindb.events import EventTypes, Event
|
||||||
|
|
||||||
@ -219,15 +219,14 @@ class App(BaseApplication):
|
|||||||
else:
|
else:
|
||||||
self.block_txn_hash = block['app_hash']
|
self.block_txn_hash = block['app_hash']
|
||||||
|
|
||||||
# Check if the current block concluded any validator elections and
|
# Check the current block to see if any elections have concluded.
|
||||||
# update the locally tracked validator set
|
concluded_elections = Election.approved_elections(self.bigchaindb,
|
||||||
validator_update = ValidatorElection.approved_update(self.bigchaindb,
|
|
||||||
self.new_height,
|
self.new_height,
|
||||||
self.block_transactions)
|
self.block_transactions)
|
||||||
|
validator_update = concluded_elections.get('VALIDATOR_ELECTION')
|
||||||
update = [validator_update] if validator_update else []
|
update = [validator_update] if validator_update else []
|
||||||
|
|
||||||
# Store pre-commit state to recover in case there is a crash
|
# Store pre-commit state to recover in case there is a crash during `commit`
|
||||||
# during `commit`
|
|
||||||
pre_commit_state = PreCommitState(commit_id=PRE_COMMIT_ID,
|
pre_commit_state = PreCommitState(commit_id=PRE_COMMIT_ID,
|
||||||
height=self.new_height,
|
height=self.new_height,
|
||||||
transactions=self.block_txn_ids)
|
transactions=self.block_txn_ids)
|
||||||
|
|||||||
@ -242,24 +242,32 @@ class Election(Transaction):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def approved_update(cls, bigchain, new_height, txns):
|
def approved_elections(cls, bigchain, new_height, txns):
|
||||||
votes = {}
|
elections = {}
|
||||||
for txn in txns:
|
for txn in txns:
|
||||||
if not isinstance(txn, Vote):
|
if not isinstance(txn, Vote):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
election_id = txn.asset['id']
|
election_id = txn.asset['id']
|
||||||
election_votes = votes.get(election_id, [])
|
e = bigchain.get_transaction(election_id)
|
||||||
|
election_operation = e.OPERATION
|
||||||
|
election_operation_votes = elections.get(election_operation, {})
|
||||||
|
# Once we conclude an election of a given type, we stop looking at that election class
|
||||||
|
if type(election_operation_votes) != dict:
|
||||||
|
continue
|
||||||
|
election_votes = election_operation_votes.get(election_id, [])
|
||||||
election_votes.append(txn)
|
election_votes.append(txn)
|
||||||
votes[election_id] = election_votes
|
election_operation_votes[election_id] = election_votes
|
||||||
|
elections[election_operation] = election_operation_votes
|
||||||
|
|
||||||
election = cls.has_concluded(bigchain, election_id, election_votes, new_height)
|
election = cls.has_concluded(bigchain, election_id, election_votes, new_height)
|
||||||
# Once an election concludes any other conclusion for the same
|
|
||||||
# or any other election is invalidated
|
|
||||||
if election:
|
if election:
|
||||||
|
# Once we conclude an election, we store the result in the db
|
||||||
cls.store_election_results(bigchain, election, new_height)
|
cls.store_election_results(bigchain, election, new_height)
|
||||||
return cls.on_approval(bigchain, election, new_height)
|
# And keep the transaction filed under the election_type
|
||||||
return None
|
elections[election_operation] = election.on_approval(bigchain, election, new_height)
|
||||||
|
approved_elections = {k: v for (k, v) in elections.items() if type(v) != dict}
|
||||||
|
return approved_elections
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def on_approval(cls, bigchain, election, new_height):
|
def on_approval(cls, bigchain, election, new_height):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user