Example #1
0
def test_end_block_return_validator_updates(b, init_chain_request):
    app = App(b)
    app.init_chain(init_chain_request)

    begin_block = RequestBeginBlock()
    app.begin_block(begin_block)

    # generate a block containing a concluded validator election
    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']
    voter_keys = [v['private_key'] for v in validators]

    election, votes = generate_election(b, ValidatorElection, public_key,
                                        private_key, new_validator['election'],
                                        voter_keys)
    b.store_block(
        Block(height=1, transactions=[election.id], app_hash='')._asdict())
    b.store_bulk_transactions([election])
    Election.process_block(b, 1, [election])

    app.block_transactions = votes

    resp = app.end_block(RequestEndBlock(height=2))
    assert resp.validator_updates[0].power == new_validator['election'][
        'power']
    expected = bytes.fromhex(new_validator['election']['public_key']['value'])
    assert expected == resp.validator_updates[0].pub_key.data
Example #2
0
def test_chain_migration_election_show_shows_concluded(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']
    voter_keys = [v['private_key'] for v in validators]

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

    assert not run_election_show(Namespace(election_id=election.id), b)

    b.store_bulk_transactions([election])
    Election.process_block(b, 1, [election])

    assert run_election_show(Namespace(election_id=election.id), b) == \
        'status=ongoing'

    b.store_abci_chain(1, 'chain-X')
    b.store_block(Block(height=1,
                        transactions=[v.id for v in votes],
                        app_hash='last_app_hash')._asdict())
    Election.process_block(b, 2, votes)

    assert run_election_show(Namespace(election_id=election.id), b) == \
        f'''status=concluded
Example #3
0
def test_chain_migration_election_show_shows_inconclusive(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']
    voter_keys = [v['private_key'] for v in validators]

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

    assert not run_election_show(Namespace(election_id=election.id), b)

    Election.process_block(b, 1, [election])
    b.store_bulk_transactions([election])

    assert run_election_show(Namespace(election_id=election.id), b) == \
        'status=ongoing'

    b.store_block(Block(height=1, transactions=[], app_hash='')._asdict())
    b.store_validator_set(2, [v['storage'] for v in validators])

    assert run_election_show(Namespace(election_id=election.id), b) == \
        'status=ongoing'

    b.store_block(Block(height=2, transactions=[], app_hash='')._asdict())
    # TODO insert yet another block here when upgrading to Tendermint 0.22.4.

    assert run_election_show(Namespace(election_id=election.id), b) == \
        'status=inconclusive'
Example #4
0
def test_chain_migration_election_show_shows_concluded(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']
    voter_keys = [v['private_key'] for v in validators]

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

    assert not run_election_show(Namespace(election_id=election.id), b)

    b.store_bulk_transactions([election])
    Election.process_block(b, 1, [election])

    assert run_election_show(Namespace(election_id=election.id), b) == \
        'status=ongoing'

    b.store_abci_chain(1, 'chain-X')
    b.store_block(
        Block(height=1,
              transactions=[v.id for v in votes],
              app_hash='last_app_hash')._asdict())
    Election.process_block(b, 2, votes)

    assert run_election_show(Namespace(election_id=election.id), b) == \
        f'''status=concluded
Example #5
0
def test_chain_migration_election_show_shows_inconclusive(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']
    voter_keys = [v['private_key'] for v in validators]

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

    assert not run_election_show(Namespace(election_id=election.id), b)

    Election.process_block(b, 1, [election])
    b.store_bulk_transactions([election])

    assert run_election_show(Namespace(election_id=election.id), b) == \
        'status=ongoing'

    b.store_block(Block(height=1, transactions=[], app_hash='')._asdict())
    b.store_validator_set(2, [v['storage'] for v in validators])

    assert run_election_show(Namespace(election_id=election.id), b) == \
        'status=ongoing'

    b.store_block(Block(height=2, transactions=[], app_hash='')._asdict())
    # TODO insert yet another block here when upgrading to Tendermint 0.22.4.

    assert run_election_show(Namespace(election_id=election.id), b) == \
        'status=inconclusive'
Example #6
0
def test_end_block_return_validator_updates(b, init_chain_request):
    app = App(b)
    app.init_chain(init_chain_request)

    begin_block = RequestBeginBlock()
    app.begin_block(begin_block)

    # generate a block containing a concluded validator election
    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']
    voter_keys = [v['private_key'] for v in validators]

    election, votes = generate_election(b,
                                        ValidatorElection,
                                        public_key, private_key,
                                        new_validator['election'],
                                        voter_keys)
    b.store_block(Block(height=1, transactions=[election.id],
                        app_hash='')._asdict())
    b.store_bulk_transactions([election])
    Election.process_block(b, 1, [election])

    app.block_transactions = votes

    resp = app.end_block(RequestEndBlock(height=2))
    assert resp.validator_updates[0].power == new_validator['election']['power']
    expected = bytes.fromhex(new_validator['election']['public_key']['value'])
    assert expected == resp.validator_updates[0].pub_key.data
Example #7
0
def test_process_block_approves_after_pending_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']
    voter_keys = [v['private_key'] for v in validators]

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

    another_validator = generate_validators([1])[0]

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

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

    txs += [election]
    total_votes += votes

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

    Election.process_block(b, 2, 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)['is_concluded']
    assert not b.get_election(txs[1].id)['is_concluded']
    assert b.get_election(txs[2].id)['is_concluded']

    assert b.get_latest_abci_chain() == {'height': 2,
                                         'chain_id': 'chain-X-migrated-at-height-1',
                                         'is_synced': False}
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.process_block(b, 4, [tx_vote0]) == []
    assert Election.process_block(b, 4, [tx_vote0, tx_vote1]) == []

    update = Election.process_block(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.process_block(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
Example #9
0
def test_process_block_approves_after_pending_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']
    voter_keys = [v['private_key'] for v in validators]

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

    another_validator = generate_validators([1])[0]

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

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

    txs += [election]
    total_votes += votes

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

    Election.process_block(b, 2, 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)['is_concluded']
    assert not b.get_election(txs[1].id)['is_concluded']
    assert b.get_election(txs[2].id)['is_concluded']

    assert b.get_latest_abci_chain() == {
        'height': 2,
        'chain_id': 'chain-X-migrated-at-height-1',
        'is_synced': False
    }
Example #10
0
def rollback(b):
    pre_commit = b.get_pre_commit_state()

    if pre_commit is None:
        # the pre_commit record is first stored in the first `end_block`
        return

    latest_block = b.get_latest_block()
    if latest_block is None:
        logger.error('Found precommit state but no blocks!')
        sys.exit(1)

    # NOTE: the pre-commit state is always at most 1 block ahead of the commited state
    if latest_block['height'] < pre_commit['height']:
        Election.rollback(b, pre_commit['height'], pre_commit['transactions'])
        b.delete_transactions(pre_commit['transactions'])
Example #11
0
    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']

        validator_update = Election.process_block(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=validator_update)
Example #12
0
    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

        # store pre-commit state to recover in case there is a crash during
        # `end_block` or `commit`
        logger.debug(f'Updating pre-commit state: {self.new_height}')
        pre_commit_state = dict(height=self.new_height,
                                transactions=self.block_txn_ids)
        self.bigchaindb.store_pre_commit_state(pre_commit_state)

        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']

        validator_update = Election.process_block(self.bigchaindb,
                                                  self.new_height,
                                                  self.block_transactions)

        return ResponseEndBlock(validator_updates=validator_update)
Example #13
0
def gen_vote(election, i, ed25519_node_keys):
    (input_i, votes_i, key_i) = to_inputs(election, i, ed25519_node_keys)
    election_pub_key = Election.to_public_key(election.id)
    return Vote.generate([input_i],
                         [([election_pub_key], votes_i)],
                         election_id=election.id)\
        .sign([key_i.private_key])
Example #14
0
def rollback(b):
    pre_commit = b.get_pre_commit_state()

    if pre_commit is None:
        # the pre_commit record is first stored in the first `end_block`
        return

    latest_block = b.get_latest_block()
    if latest_block is None:
        logger.error('Found precommit state but no blocks!')
        sys.exit(1)

    # NOTE: the pre-commit state is always at most 1 block ahead of the commited state
    if latest_block['height'] < pre_commit['height']:
        Election.rollback(b, pre_commit['height'], pre_commit['transactions'])
        b.delete_transactions(pre_commit['transactions'])
Example #15
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
Example #16
0
def test_process_block_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']
    voter_keys = [v['private_key'] for v in validators]

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

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

    txs += [election]
    total_votes += votes

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

    Election.process_block(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)['is_concluded']
    assert not b.get_election(txs[1].id)['is_concluded']
Example #17
0
def test_process_block_approves_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']
    voter_keys = [v['private_key'] for v in validators]

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

    another_validator = generate_validators([1])[0]

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

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

    Election.process_block(b, 2, 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)['is_concluded']
    assert not b.get_election(txs[1].id)['is_concluded']
Example #18
0
def generate_election(b, cls, public_key, private_key, asset_data):
    voters = cls.recipients(b)
    election = cls.generate([public_key], voters, asset_data,
                            None).sign([private_key])

    votes = [
        Vote.generate([election.to_inputs()[i]],
                      [([Election.to_public_key(election.id)], power)],
                      election.id) for i, (_, power) in enumerate(voters)
    ]

    return election, votes
Example #19
0
def test_process_block_approves_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']
    voter_keys = [v['private_key'] for v in validators]

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

    another_validator = generate_validators([1])[0]

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

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

    Election.process_block(b, 2, 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)['is_concluded']
    assert not b.get_election(txs[1].id)['is_concluded']
Example #20
0
def test_process_block_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')
    Election.process_block(b, 1, txs)
    b.store_block(Block(height=1,
                        transactions=[tx.id for tx in txs],
                        app_hash='')._asdict())
    b.store_bulk_transactions(txs)

    Election.process_block(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)['is_concluded']
    assert not b.get_election(txs[1].id)['is_concluded']
Example #21
0
def test_process_block_does_not_approve_after_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']
    voter_keys = [v['private_key'] for v in validators]

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

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

    second_election, second_votes = generate_election(b,
                                                      ChainMigrationElection,
                                                      public_key, private_key,
                                                      {}, voter_keys)

    Election.process_block(b, 2, total_votes + [second_election])

    b.store_block(
        Block(height=2,
              transactions=[v.id for v in total_votes + [second_election]],
              app_hash='')._asdict())

    b.store_abci_chain(1, 'chain-X')
    Election.process_block(b, 3, second_votes)

    assert not b.get_election(second_election.id)['is_concluded']
    assert b.get_latest_abci_chain() == {
        'height': 1,
        'chain_id': 'chain-X',
        'is_synced': True
    }
Example #22
0
def test_process_block_does_not_approve_after_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']
    voter_keys = [v['private_key'] for v in validators]

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

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

    second_election, second_votes = generate_election(b,
                                                      ChainMigrationElection,
                                                      public_key, private_key,
                                                      {},
                                                      voter_keys)

    Election.process_block(b, 2, total_votes + [second_election])

    b.store_block(Block(height=2,
                        transactions=[v.id for v in total_votes + [second_election]],
                        app_hash='')._asdict())

    b.store_abci_chain(1, 'chain-X')
    Election.process_block(b, 3, second_votes)

    assert not b.get_election(second_election.id)['is_concluded']
    assert b.get_latest_abci_chain() == {'height': 1,
                                         'chain_id': 'chain-X',
                                         'is_synced': True}
Example #23
0
def test_approved_elections_gracefully_handles_empty_block(b):
    Election.approved_elections(b, 1, [])
Example #24
0
def test_process_block_gracefully_handles_empty_block(b):
    Election.process_block(b, 1, [])
Example #25
0
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.process_block(b, 4, [tx_vote0]) == []
    assert Election.process_block(b, 4, [tx_vote0, tx_vote1]) == []

    update = Election.process_block(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.process_block(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
Example #26
0
def test_process_block_gracefully_handles_empty_block(b):
    Election.process_block(b, 1, [])