예제 #1
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}
예제 #2
0
def test_rollback_pre_commit_state_after_crash(b):
    validators = generate_validators([1] * 4)
    b.store_validator_set(1, [v['storage'] for v in validators])
    b.store_block(Block(height=1, transactions=[], app_hash='')._asdict())

    public_key = validators[0]['public_key']
    private_key = validators[0]['private_key']
    voter_keys = [v['private_key'] for v in validators]

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

    total_votes = votes
    txs = [migration_election, *votes]

    new_validator = generate_validators([1])[0]
    validator_election, votes = generate_election(b, ValidatorElection,
                                                  public_key, private_key,
                                                  new_validator['election'],
                                                  voter_keys)

    total_votes += votes
    txs += [validator_election, *votes]

    b.store_bulk_transactions(txs)
    b.store_abci_chain(2, 'new_chain')
    b.store_validator_set(2, [v['storage'] for v in validators])
    # TODO change to `4` when upgrading to Tendermint 0.22.4.
    b.store_validator_set(3, [new_validator['storage']])
    b.store_election(migration_election.id, 2, is_concluded=False)
    b.store_election(validator_election.id, 2, is_concluded=True)

    # no pre-commit state
    rollback(b)

    for tx in txs:
        assert b.get_transaction(tx.id)
    assert b.get_latest_abci_chain()
    assert len(b.get_validator_change()['validators']) == 1
    assert b.get_election(migration_election.id)
    assert b.get_election(validator_election.id)

    b.store_pre_commit_state({
        'height': 2,
        'transactions': [tx.id for tx in txs]
    })

    rollback(b)

    for tx in txs:
        assert not b.get_transaction(tx.id)
    assert not b.get_latest_abci_chain()
    assert len(b.get_validator_change()['validators']) == 4
    assert len(b.get_validator_change(2)['validators']) == 4
    assert not b.get_election(migration_election.id)
    assert not b.get_election(validator_election.id)
예제 #3
0
def test_rollback_pre_commit_state_after_crash(b):
    validators = generate_validators([1] * 4)
    b.store_validator_set(1, [v['storage'] for v in validators])
    b.store_block(Block(height=1, transactions=[], app_hash='')._asdict())

    public_key = validators[0]['public_key']
    private_key = validators[0]['private_key']
    voter_keys = [v['private_key'] for v in validators]

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

    total_votes = votes
    txs = [migration_election, *votes]

    new_validator = generate_validators([1])[0]
    validator_election, votes = generate_election(b,
                                                  ValidatorElection,
                                                  public_key, private_key,
                                                  new_validator['election'],
                                                  voter_keys)

    total_votes += votes
    txs += [validator_election, *votes]

    b.store_bulk_transactions(txs)
    b.store_abci_chain(2, 'new_chain')
    b.store_validator_set(2, [v['storage'] for v in validators])
    # TODO change to `4` when upgrading to Tendermint 0.22.4.
    b.store_validator_set(3, [new_validator['storage']])
    b.store_election(migration_election.id, 2, is_concluded=False)
    b.store_election(validator_election.id, 2, is_concluded=True)

    # no pre-commit state
    rollback(b)

    for tx in txs:
        assert b.get_transaction(tx.id)
    assert b.get_latest_abci_chain()
    assert len(b.get_validator_change()['validators']) == 1
    assert b.get_election(migration_election.id)
    assert b.get_election(validator_election.id)

    b.store_pre_commit_state({'height': 2, 'transactions': [tx.id for tx in txs]})

    rollback(b)

    for tx in txs:
        assert not b.get_transaction(tx.id)
    assert not b.get_latest_abci_chain()
    assert len(b.get_validator_change()['validators']) == 4
    assert len(b.get_validator_change(2)['validators']) == 4
    assert not b.get_election(migration_election.id)
    assert not b.get_election(validator_election.id)
예제 #4
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
    }
예제 #5
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
예제 #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
예제 #7
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
예제 #8
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
예제 #9
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'
예제 #10
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'
예제 #11
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
예제 #12
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
    }
예제 #13
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}
예제 #14
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']
예제 #15
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']
예제 #16
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']
예제 #17
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']