예제 #1
0
파일: core.py 프로젝트: muawiakh/bigchaindb
    def end_block(self, request_end_block):
        """Calculate block hash using transaction ids and previous block
        hash to be stored in the next block.

        Args:
            height (int): new height of the chain.
        """

        self.abort_if_abci_chain_is_not_synced()

        chain_shift = 0 if self.chain is None else self.chain['height']

        height = request_end_block.height + chain_shift
        self.new_height = height
        block_txn_hash = calculate_hash(self.block_txn_ids)
        block = self.bigchaindb.get_latest_block()

        if self.block_txn_ids:
            self.block_txn_hash = calculate_hash(
                [block['app_hash'], block_txn_hash])
        else:
            self.block_txn_hash = block['app_hash']

        # Process all concluded elections in the current block and get any update to the validator set
        update = Election.approved_elections(self.bigchaindb, self.new_height,
                                             self.block_transactions)

        # Store pre-commit state to recover in case there is a crash  during `commit`
        pre_commit_state = PreCommitState(commit_id=PRE_COMMIT_ID,
                                          height=self.new_height,
                                          transactions=self.block_txn_ids)
        logger.debug('Updating PreCommitState: %s', self.new_height)
        self.bigchaindb.store_pre_commit_state(pre_commit_state._asdict())
        return ResponseEndBlock(validator_updates=update)
예제 #2
0
def test_approved_elections_concludes_all_elections(b):
    validators = generate_validators([1] * 4)
    b.store_validator_set(1, [v['storage'] for v in validators])

    new_validator = generate_validators([1])[0]

    public_key = validators[0]['public_key']
    private_key = validators[0]['private_key']
    election, votes = generate_election(b,
                                        ValidatorElection,
                                        public_key, private_key,
                                        new_validator['election'])
    txs = [election]
    total_votes = votes

    election, votes = generate_election(b,
                                        ChainMigrationElection,
                                        public_key, private_key,
                                        {})

    txs += [election]
    total_votes += votes

    b.store_abci_chain(1, 'chain-X')
    b.store_block(Block(height=1,
                        transactions=[tx.id for tx in txs],
                        app_hash='')._asdict())
    b.store_bulk_transactions(txs)

    Election.approved_elections(b, 1, total_votes)

    validators = b.get_validators()
    assert len(validators) == 5
    assert new_validator['storage'] in validators

    chain = b.get_latest_abci_chain()
    assert chain
    assert chain == {
        'height': 2,
        'is_synced': False,
        'chain_id': 'chain-X-migrated-at-height-1',
    }

    for tx in txs:
        election = b.get_election(tx.id)
        assert election
예제 #3
0
def test_approved_elections_applies_only_one_validator_update(b):
    validators = generate_validators([1] * 4)
    b.store_validator_set(1, [v['storage'] for v in validators])

    new_validator = generate_validators([1])[0]

    public_key = validators[0]['public_key']
    private_key = validators[0]['private_key']
    election, votes = generate_election(b,
                                        ValidatorElection,
                                        public_key, private_key,
                                        new_validator['election'])
    txs = [election]
    total_votes = votes

    another_validator = generate_validators([1])[0]

    election, votes = generate_election(b,
                                        ValidatorElection,
                                        public_key, private_key,
                                        another_validator['election'])
    txs += [election]
    total_votes += votes

    b.store_block(Block(height=1,
                        transactions=[tx.id for tx in txs],
                        app_hash='')._asdict())
    b.store_bulk_transactions(txs)

    Election.approved_elections(b, 1, total_votes)

    validators = b.get_validators()
    assert len(validators) == 5
    assert new_validator['storage'] in validators
    assert another_validator['storage'] not in validators

    assert b.get_election(txs[0].id)
    assert not b.get_election(txs[1].id)
예제 #4
0
def test_approved_elections_applies_only_one_migration(b):
    validators = generate_validators([1] * 4)
    b.store_validator_set(1, [v['storage'] for v in validators])

    public_key = validators[0]['public_key']
    private_key = validators[0]['private_key']
    election, votes = generate_election(b,
                                        ChainMigrationElection,
                                        public_key, private_key,
                                        {})
    txs = [election]
    total_votes = votes

    election, votes = generate_election(b,
                                        ChainMigrationElection,
                                        public_key, private_key,
                                        {})

    txs += [election]
    total_votes += votes

    b.store_abci_chain(1, 'chain-X')
    b.store_block(Block(height=1,
                        transactions=[tx.id for tx in txs],
                        app_hash='')._asdict())
    b.store_bulk_transactions(txs)

    Election.approved_elections(b, 1, total_votes)
    chain = b.get_latest_abci_chain()
    assert chain
    assert chain == {
        'height': 2,
        'is_synced': False,
        'chain_id': 'chain-X-migrated-at-height-1',
    }

    assert b.get_election(txs[0].id)
    assert not b.get_election(txs[1].id)
예제 #5
0
def test_approved_elections_gracefully_handles_empty_block(b):
    Election.approved_elections(b, 1, [])
def test_get_validator_update(b, node_keys, node_key, ed25519_node_keys):
    reset_validator_set(b, node_keys, 1)

    power = 1
    public_key = '9B3119650DF82B9A5D8A12E38953EA47475C09F0C48A4E6A0ECE182944B24403'
    public_key64 = public_key_to_base64(public_key)
    new_validator = {
        'public_key': {
            'value': public_key,
            'type': 'ed25519-base16'
        },
        'node_id': 'some_node_id',
        'power': power
    }
    voters = ValidatorElection.recipients(b)
    election = ValidatorElection.generate([node_key.public_key], voters,
                                          new_validator).sign(
                                              [node_key.private_key])
    # store election
    b.store_bulk_transactions([election])

    tx_vote0 = gen_vote(election, 0, ed25519_node_keys)
    tx_vote1 = gen_vote(election, 1, ed25519_node_keys)
    tx_vote2 = gen_vote(election, 2, ed25519_node_keys)

    assert not election.has_concluded(b, [tx_vote0])
    assert not election.has_concluded(b, [tx_vote0, tx_vote1])
    assert election.has_concluded(b, [tx_vote0, tx_vote1, tx_vote2])

    assert Election.approved_elections(b, 4, [tx_vote0]) == []
    assert Election.approved_elections(b, 4, [tx_vote0, tx_vote1]) == []

    update = Election.approved_elections(b, 4, [tx_vote0, tx_vote1, tx_vote2])
    assert len(update) == 1
    update_public_key = codecs.encode(update[0].pub_key.data,
                                      'base64').decode().rstrip('\n')
    assert update_public_key == public_key64

    # remove validator
    power = 0
    new_validator = {
        'public_key': {
            'value': public_key,
            'type': 'ed25519-base16'
        },
        'node_id': 'some_node_id',
        'power': power
    }
    voters = ValidatorElection.recipients(b)
    election = ValidatorElection.generate([node_key.public_key], voters,
                                          new_validator).sign(
                                              [node_key.private_key])
    # store election
    b.store_bulk_transactions([election])

    tx_vote0 = gen_vote(election, 0, ed25519_node_keys)
    tx_vote1 = gen_vote(election, 1, ed25519_node_keys)
    tx_vote2 = gen_vote(election, 2, ed25519_node_keys)

    b.store_bulk_transactions([tx_vote0, tx_vote1])

    update = Election.approved_elections(b, 9, [tx_vote2])
    assert len(update) == 1
    update_public_key = codecs.encode(update[0].pub_key.data,
                                      'base64').decode().rstrip('\n')
    assert update_public_key == public_key64

    # assert that the public key is not a part of the current validator set
    for v in b.get_validators(10):
        assert not v['public_key']['value'] == public_key64