Ejemplo n.º 1
0
def test_upsert_validator_invalid_election(b_mock, new_validator, node_key, fixed_seed_election):
    voters = ValidatorElection.recipients(b_mock)
    duplicate_election = ValidatorElection.generate([node_key.public_key],
                                                    voters,
                                                    new_validator, None).sign([node_key.private_key])

    with pytest.raises(DuplicateTransaction):
        fixed_seed_election.validate(b_mock, [duplicate_election])

    b_mock.store_bulk_transactions([fixed_seed_election])

    with pytest.raises(DuplicateTransaction):
        duplicate_election.validate(b_mock)

    # Try creating an election with incomplete voter set
    invalid_election = ValidatorElection.generate([node_key.public_key],
                                                  voters[1:],
                                                  new_validator, None).sign([node_key.private_key])

    with pytest.raises(UnequalValidatorSet):
        invalid_election.validate(b_mock)

    recipients = ValidatorElection.recipients(b_mock)
    altered_recipients = []
    for r in recipients:
        ([r_public_key], voting_power) = r
        altered_recipients.append(([r_public_key], voting_power - 1))

    # Create a transaction which doesn't enfore the network power
    tx_election = ValidatorElection.generate([node_key.public_key],
                                             altered_recipients,
                                             new_validator, None).sign([node_key.private_key])

    with pytest.raises(UnequalValidatorSet):
        tx_election.validate(b_mock)
def test_upsert_validator(b, node_key, node_keys, ed25519_node_keys):
    import time
    import requests

    if b.get_latest_block()['height'] == 0:
        generate_block(b)

    (node_pub, _) = list(node_keys.items())[0]

    validators = [{
        'pub_key': {
            'type': 'ed25519',
            'data': node_pub
        },
        'voting_power': 10
    }]

    latest_block = b.get_latest_block()
    # reset the validator set
    b.store_validator_set(latest_block['height'], validators,
                          'previous_election_id')

    power = 1
    public_key = '9B3119650DF82B9A5D8A12E38953EA47475C09F0C48A4E6A0ECE182944B24403'
    public_key64 = public_key_to_base64(public_key)
    new_validator = {
        'public_key': public_key,
        'node_id': 'some_node_id',
        'power': power
    }

    voters = ValidatorElection.recipients(b)
    election = ValidatorElection.generate([node_key.public_key], voters,
                                          new_validator,
                                          None).sign([node_key.private_key])
    code, message = b.write_transaction(election, 'broadcast_tx_commit')
    assert code == 202
    time.sleep(3)

    assert b.get_transaction(election.id)

    tx_vote = gen_vote(election, 0, ed25519_node_keys)
    assert tx_vote.validate(b)
    code, message = b.write_transaction(tx_vote, 'broadcast_tx_commit')
    assert code == 202
    time.sleep(3)

    resp = requests.get(b.endpoint + 'validators')
    validator_pub_keys = []
    for v in resp.json()['result']['validators']:
        validator_pub_keys.append(v['pub_key']['value'])

    assert (public_key64 in validator_pub_keys)
    new_validator_set = b.get_validators()
    validator_pub_keys = []
    for v in new_validator_set:
        validator_pub_keys.append(v['pub_key']['data'])

    assert (public_key64 in validator_pub_keys)
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
Ejemplo n.º 4
0
def test_upsert_validator_invalid_power_election(b_mock, new_validator, node_key):
    voters = ValidatorElection.recipients(b_mock)
    new_validator['power'] = 30

    election = ValidatorElection.generate([node_key.public_key],
                                          voters,
                                          new_validator, None).sign([node_key.private_key])
    with pytest.raises(InvalidPowerChange):
        election.validate(b_mock)
Ejemplo n.º 5
0
def test_upsert_validator(b, node_key, node_keys, ed25519_node_keys):

    if b.get_latest_block()['height'] == 0:
        generate_block(b)

    (node_pub, _) = list(node_keys.items())[0]

    validators = [{
        'public_key': {
            'type': 'ed25519-base64',
            'value': node_pub
        },
        'voting_power': 10
    }]

    latest_block = b.get_latest_block()
    # reset the validator set
    b.store_validator_set(latest_block['height'], validators)
    generate_block(b)

    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,
                                          None).sign([node_key.private_key])
    code, message = b.write_transaction(election, BROADCAST_TX_COMMIT)
    assert code == 202
    assert b.get_transaction(election.id)

    tx_vote = gen_vote(election, 0, ed25519_node_keys)
    assert tx_vote.validate(b)
    code, message = b.write_transaction(tx_vote, BROADCAST_TX_COMMIT)
    assert code == 202

    resp = b.get_validators()
    validator_pub_keys = []
    for v in resp:
        validator_pub_keys.append(v['public_key']['value'])

    assert (public_key64 in validator_pub_keys)
    new_validator_set = b.get_validators()
    validator_pub_keys = []
    for v in new_validator_set:
        validator_pub_keys.append(v['public_key']['value'])

    assert (public_key64 in validator_pub_keys)
Ejemplo n.º 6
0
def test_valid_election_conclude(b_mock, valid_election, ed25519_node_keys):

    # Node 0: cast vote
    tx_vote0 = gen_vote(valid_election, 0, ed25519_node_keys)

    # check if the vote is valid even before the election doesn't exist
    with pytest.raises(ValidationError):
        assert tx_vote0.validate(b_mock)

    # store election
    b_mock.store_bulk_transactions([valid_election])
    # cannot conclude election as not votes exist
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id)

    # validate vote
    assert tx_vote0.validate(b_mock)
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote0])

    b_mock.store_bulk_transactions([tx_vote0])
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id)

    # Node 1: cast vote
    tx_vote1 = gen_vote(valid_election, 1, ed25519_node_keys)

    # Node 2: cast vote
    tx_vote2 = gen_vote(valid_election, 2, ed25519_node_keys)

    # Node 3: cast vote
    tx_vote3 = gen_vote(valid_election, 3, ed25519_node_keys)

    assert tx_vote1.validate(b_mock)
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote1])

    # 2/3 is achieved in the same block so the election can be.has_concludedd
    assert ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote1, tx_vote2])

    b_mock.store_bulk_transactions([tx_vote1])
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id)

    assert tx_vote2.validate(b_mock)
    assert tx_vote3.validate(b_mock)

    # conclusion can be triggered my different votes in the same block
    assert ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote2])
    assert ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote2, tx_vote3])

    b_mock.store_bulk_transactions([tx_vote2])

    # Once the blockchain records >2/3 of the votes the election is assumed to be.has_concludedd
    # so any invocation of `.has_concluded` for that election should return False
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id)

    # Vote is still valid but the election cannot be.has_concludedd as it it assmed that it has
    # been.has_concludedd before
    assert tx_vote3.validate(b_mock)
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote3])
def test_valid_election_conclude(b_mock, valid_election, ed25519_node_keys):

    # Node 0: cast vote
    tx_vote0 = gen_vote(valid_election, 0, ed25519_node_keys)

    # check if the vote is valid even before the election doesn't exist
    with pytest.raises(ValidationError):
        assert tx_vote0.validate(b_mock)

    # store election
    b_mock.store_bulk_transactions([valid_election])
    # cannot conclude election as not votes exist
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id)

    # validate vote
    assert tx_vote0.validate(b_mock)
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote0])

    b_mock.store_bulk_transactions([tx_vote0])
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id)

    # Node 1: cast vote
    tx_vote1 = gen_vote(valid_election, 1, ed25519_node_keys)

    # Node 2: cast vote
    tx_vote2 = gen_vote(valid_election, 2, ed25519_node_keys)

    # Node 3: cast vote
    tx_vote3 = gen_vote(valid_election, 3, ed25519_node_keys)

    assert tx_vote1.validate(b_mock)
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote1])

    # 2/3 is achieved in the same block so the election can be.has_concludedd
    assert ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote1, tx_vote2])

    b_mock.store_bulk_transactions([tx_vote1])
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id)

    assert tx_vote2.validate(b_mock)
    assert tx_vote3.validate(b_mock)

    # conclusion can be triggered my different votes in the same block
    assert ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote2])
    assert ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote2, tx_vote3])

    b_mock.store_bulk_transactions([tx_vote2])

    # Once the blockchain records >2/3 of the votes the election is assumed to be.has_concludedd
    # so any invocation of `.has_concluded` for that election should return False
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id)

    # Vote is still valid but the election cannot be.has_concludedd as it it assmed that it has
    # been.has_concludedd before
    assert tx_vote3.validate(b_mock)
    assert not ValidatorElection.has_concluded(b_mock, valid_election.id, [tx_vote3])
Ejemplo n.º 8
0
def test_upsert_validator_invalid_inputs_election(b_mock, new_validator, node_key):
    from bigchaindb.common.crypto import generate_key_pair

    alice = generate_key_pair()
    voters = ValidatorElection.recipients(b_mock)
    election = ValidatorElection.generate([node_key.public_key, alice.public_key],
                                          voters,
                                          new_validator, None).sign([node_key.private_key, alice.private_key])
    with pytest.raises(MultipleInputsError):
        election.validate(b_mock)
Ejemplo n.º 9
0
def test_upsert_validator_invalid_election_public_key(b_mock, new_validator, node_key):
    from bigchaindb.common.exceptions import InvalidPublicKey

    for iv in ['ed25519-base32', 'ed25519-base64']:
        new_validator['public_key']['type'] = iv
        voters = ValidatorElection.recipients(b_mock)

        with pytest.raises(InvalidPublicKey):
            ValidatorElection.generate([node_key.public_key],
                                       voters,
                                       new_validator, None).sign([node_key.private_key])
Ejemplo n.º 10
0
def test_upsert_validator(b, node_key, node_keys, ed25519_node_keys):
    import time
    import requests

    if b.get_latest_block()['height'] == 0:
        generate_block(b)

    (node_pub, _) = list(node_keys.items())[0]

    validators = [{'public_key': {'type': 'ed25519-base64', 'value': node_pub},
                   'voting_power': 10}]

    latest_block = b.get_latest_block()
    # reset the validator set
    b.store_validator_set(latest_block['height'], validators)

    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, None).sign([node_key.private_key])
    code, message = b.write_transaction(election, 'broadcast_tx_commit')
    assert code == 202
    time.sleep(3)

    assert b.get_transaction(election.id)

    tx_vote = gen_vote(election, 0, ed25519_node_keys)
    assert tx_vote.validate(b)
    code, message = b.write_transaction(tx_vote, 'broadcast_tx_commit')
    assert code == 202
    time.sleep(3)

    resp = requests.get(b.endpoint + 'validators')
    validator_pub_keys = []
    for v in resp.json()['result']['validators']:
        validator_pub_keys.append(v['pub_key']['value'])

    assert (public_key64 in validator_pub_keys)
    new_validator_set = b.get_validators()
    validator_pub_keys = []
    for v in new_validator_set:
        validator_pub_keys.append(v['public_key']['value'])

    assert (public_key64 in validator_pub_keys)
Ejemplo n.º 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.
        """

        height = request_end_block.height
        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']

        # Check if the current block concluded any validator elections and
        # update the locally tracked validator set
        validator_updates = ValidatorElection.get_validator_update(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_updates)
Ejemplo n.º 12
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 = ValidatorElection.to_public_key(election.id)
    return Vote.generate([input_i],
                         [([election_pub_key], votes_i)],
                         election_id=election.id)\
        .sign([key_i.private_key])
def test_upsert_validator_delegate_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys):
    alice = generate_key_pair()

    b_mock.store_bulk_transactions([valid_upsert_validator_election])

    input0 = valid_upsert_validator_election.to_inputs()[0]
    votes = valid_upsert_validator_election.outputs[0].amount
    public_key0 = input0.owners_before[0]
    key0 = ed25519_node_keys[public_key0]

    delegate_vote = Vote.generate([input0],
                                  [([alice.public_key], 3), ([key0.public_key], votes-3)],
                                  election_id=valid_upsert_validator_election.id)\
        .sign([key0.private_key])

    assert delegate_vote.validate(b_mock)

    b_mock.store_bulk_transactions([delegate_vote])
    election_pub_key = ValidatorElection.to_public_key(valid_upsert_validator_election.id)

    alice_votes = delegate_vote.to_inputs()[0]
    alice_casted_vote = Vote.generate([alice_votes],
                                      [([election_pub_key], 3)],
                                      election_id=valid_upsert_validator_election.id)\
        .sign([alice.private_key])
    assert alice_casted_vote.validate(b_mock)

    key0_votes = delegate_vote.to_inputs()[1]
    key0_casted_vote = Vote.generate([key0_votes],
                                     [([election_pub_key], votes-3)],
                                     election_id=valid_upsert_validator_election.id)\
        .sign([key0.private_key])
    assert key0_casted_vote.validate(b_mock)
def gen_vote(election, i, ed25519_node_keys):
    (input_i, votes_i, key_i) = to_inputs(election, i, ed25519_node_keys)
    election_pub_key = ValidatorElection.to_public_key(election.id)
    return ValidatorElectionVote.generate([input_i],
                                          [([election_pub_key], votes_i)],
                                          election_id=election.id)\
                                .sign([key_i.private_key])
def test_upsert_validator_delegate_election_vote(b_mock, valid_election,
                                                 ed25519_node_keys):
    alice = generate_key_pair()

    b_mock.store_bulk_transactions([valid_election])

    input0 = valid_election.to_inputs()[0]
    votes = valid_election.outputs[0].amount
    public_key0 = input0.owners_before[0]
    key0 = ed25519_node_keys[public_key0]

    delegate_vote = ValidatorElectionVote.generate([input0],
                                                   [([alice.public_key], 3), ([key0.public_key], votes-3)],
                                                   election_id=valid_election.id)\
                                         .sign([key0.private_key])

    assert delegate_vote.validate(b_mock)

    b_mock.store_bulk_transactions([delegate_vote])
    election_pub_key = ValidatorElection.to_public_key(valid_election.id)

    alice_votes = delegate_vote.to_inputs()[0]
    alice_casted_vote = ValidatorElectionVote.generate([alice_votes],
                                                       [([election_pub_key], 3)],
                                                       election_id=valid_election.id)\
                                             .sign([alice.private_key])
    assert alice_casted_vote.validate(b_mock)

    key0_votes = delegate_vote.to_inputs()[1]
    key0_casted_vote = ValidatorElectionVote.generate([key0_votes],
                                                      [([election_pub_key], votes-3)],
                                                      election_id=valid_election.id)\
                                            .sign([key0.private_key])
    assert key0_casted_vote.validate(b_mock)
Ejemplo n.º 16
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': public_key,
        '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 ValidatorElection.has_concluded(b, election.id, [tx_vote0])
    assert not ValidatorElection.has_concluded(b, election.id,
                                               [tx_vote0, tx_vote1])
    assert ValidatorElection.has_concluded(b, election.id,
                                           [tx_vote0, tx_vote1, tx_vote2])

    assert ValidatorElection.get_validator_update(b, 4, [tx_vote0]) == []
    assert ValidatorElection.get_validator_update(b, 4,
                                                  [tx_vote0, tx_vote1]) == []

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

    b.store_bulk_transactions([tx_vote0, tx_vote1])

    update = ValidatorElection.get_validator_update(b, 4, [tx_vote2])
    print('update', update)
    update_public_key = codecs.encode(update[0].pub_key.data,
                                      'base64').decode().rstrip('\n')
    assert len(update) == 1
    assert update_public_key == public_key64
Ejemplo n.º 17
0
def vote(election, voter, keys, b):
    election_input = election.to_inputs()[voter]
    votes = election.outputs[voter].amount
    public_key = election_input.owners_before[0]
    key = keys[public_key]

    election_pub_key = ValidatorElection.to_public_key(election.id)

    v = ValidatorElectionVote.generate([election_input],
                                       [([election_pub_key], votes)],
                                       election_id=election.id)\
                             .sign([key.private_key])
    b.store_bulk_transactions([v])
    return v
def test_upsert_validator_valid_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys):
    b_mock.store_bulk_transactions([valid_upsert_validator_election])

    input0 = valid_upsert_validator_election.to_inputs()[0]
    votes = valid_upsert_validator_election.outputs[0].amount
    public_key0 = input0.owners_before[0]
    key0 = ed25519_node_keys[public_key0]

    election_pub_key = ValidatorElection.to_public_key(valid_upsert_validator_election.id)

    vote = Vote.generate([input0],
                         [([election_pub_key], votes)],
                         election_id=valid_upsert_validator_election.id)\
        .sign([key0.private_key])
    assert vote.validate(b_mock)
def test_upsert_validator_valid_election_vote(b_mock, valid_election, ed25519_node_keys):
    b_mock.store_bulk_transactions([valid_election])

    input0 = valid_election.to_inputs()[0]
    votes = valid_election.outputs[0].amount
    public_key0 = input0.owners_before[0]
    key0 = ed25519_node_keys[public_key0]

    election_pub_key = ValidatorElection.to_public_key(valid_election.id)

    vote = ValidatorElectionVote.generate([input0],
                                          [([election_pub_key], votes)],
                                          election_id=valid_election.id)\
                                .sign([key0.private_key])
    assert vote.validate(b_mock)
def test_upsert_validator_valid_non_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys):
    b_mock.store_bulk_transactions([valid_upsert_validator_election])

    input0 = valid_upsert_validator_election.to_inputs()[0]
    votes = valid_upsert_validator_election.outputs[0].amount
    public_key0 = input0.owners_before[0]
    key0 = ed25519_node_keys[public_key0]

    election_pub_key = ValidatorElection.to_public_key(valid_upsert_validator_election.id)

    # Ensure that threshold conditions are now allowed
    with pytest.raises(ValidationError):
        Vote.generate([input0],
                      [([election_pub_key, key0.public_key], votes)],
                      election_id=valid_upsert_validator_election.id)\
             .sign([key0.private_key])
def test_upsert_validator_valid_non_election_vote(b_mock, valid_election, ed25519_node_keys):
    b_mock.store_bulk_transactions([valid_election])

    input0 = valid_election.to_inputs()[0]
    votes = valid_election.outputs[0].amount
    public_key0 = input0.owners_before[0]
    key0 = ed25519_node_keys[public_key0]

    election_pub_key = ValidatorElection.to_public_key(valid_election.id)

    # Ensure that threshold conditions are now allowed
    with pytest.raises(ValidationError):
        ValidatorElectionVote.generate([input0],
                                       [([election_pub_key, key0.public_key], votes)],
                                       election_id=valid_election.id)\
                             .sign([key0.private_key])
Ejemplo n.º 22
0
def test_valid_election_votes_received(b_mock, valid_upsert_validator_election,
                                       ed25519_node_keys):
    alice = generate_key_pair()
    b_mock.store_bulk_transactions([valid_upsert_validator_election])
    assert valid_upsert_validator_election.get_commited_votes(b_mock) == 0

    input0 = valid_upsert_validator_election.to_inputs()[0]
    votes = valid_upsert_validator_election.outputs[0].amount
    public_key0 = input0.owners_before[0]
    key0 = ed25519_node_keys[public_key0]

    # delegate some votes to alice
    delegate_vote = Vote.generate([input0],
                                  [([alice.public_key], 4), ([key0.public_key], votes-4)],
                                  election_id=valid_upsert_validator_election.id)\
        .sign([key0.private_key])
    b_mock.store_bulk_transactions([delegate_vote])
    assert valid_upsert_validator_election.get_commited_votes(b_mock) == 0

    election_public_key = ValidatorElection.to_public_key(
        valid_upsert_validator_election.id)
    alice_votes = delegate_vote.to_inputs()[0]
    key0_votes = delegate_vote.to_inputs()[1]

    alice_casted_vote = Vote.generate([alice_votes],
                                      [([election_public_key], 2), ([alice.public_key], 2)],
                                      election_id=valid_upsert_validator_election.id)\
        .sign([alice.private_key])

    assert alice_casted_vote.validate(b_mock)
    b_mock.store_bulk_transactions([alice_casted_vote])

    # Check if the delegated vote is count as valid vote
    assert valid_upsert_validator_election.get_commited_votes(b_mock) == 2

    key0_casted_vote = Vote.generate([key0_votes],
                                     [([election_public_key], votes-4)],
                                     election_id=valid_upsert_validator_election.id)\
        .sign([key0.private_key])

    assert key0_casted_vote.validate(b_mock)
    b_mock.store_bulk_transactions([key0_casted_vote])

    assert valid_upsert_validator_election.get_commited_votes(
        b_mock) == votes - 2
def test_valid_election_votes_received(b_mock, valid_upsert_validator_election, ed25519_node_keys):
    alice = generate_key_pair()
    b_mock.store_bulk_transactions([valid_upsert_validator_election])
    assert valid_upsert_validator_election.get_commited_votes(b_mock) == 0

    input0 = valid_upsert_validator_election.to_inputs()[0]
    votes = valid_upsert_validator_election.outputs[0].amount
    public_key0 = input0.owners_before[0]
    key0 = ed25519_node_keys[public_key0]

    # delegate some votes to alice
    delegate_vote = Vote.generate([input0],
                                  [([alice.public_key], 4), ([key0.public_key], votes-4)],
                                  election_id=valid_upsert_validator_election.id)\
        .sign([key0.private_key])
    b_mock.store_bulk_transactions([delegate_vote])
    assert valid_upsert_validator_election.get_commited_votes(b_mock) == 0

    election_public_key = ValidatorElection.to_public_key(valid_upsert_validator_election.id)
    alice_votes = delegate_vote.to_inputs()[0]
    key0_votes = delegate_vote.to_inputs()[1]

    alice_casted_vote = Vote.generate([alice_votes],
                                      [([election_public_key], 2), ([alice.public_key], 2)],
                                      election_id=valid_upsert_validator_election.id)\
        .sign([alice.private_key])

    assert alice_casted_vote.validate(b_mock)
    b_mock.store_bulk_transactions([alice_casted_vote])

    # Check if the delegated vote is count as valid vote
    assert valid_upsert_validator_election.get_commited_votes(b_mock) == 2

    key0_casted_vote = Vote.generate([key0_votes],
                                     [([election_public_key], votes-4)],
                                     election_id=valid_upsert_validator_election.id)\
        .sign([key0.private_key])

    assert key0_casted_vote.validate(b_mock)
    b_mock.store_bulk_transactions([key0_casted_vote])

    assert valid_upsert_validator_election.get_commited_votes(b_mock) == votes - 2
Ejemplo n.º 24
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']

        # Check if the current block concluded any validator elections and
        # update the locally tracked validator set
        validator_update = ValidatorElection.approved_update(self.bigchaindb,
                                                             self.new_height,
                                                             self.block_transactions)
        update = [validator_update] if validator_update else []

        # 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)
Ejemplo n.º 25
0
def test_upsert_validator_valid_election(b_mock, new_validator, node_key):
    voters = ValidatorElection.recipients(b_mock)
    election = ValidatorElection.generate([node_key.public_key],
                                          voters,
                                          new_validator, None).sign([node_key.private_key])
    assert election.validate(b_mock)
Ejemplo n.º 26
0
def valid_election_b(b, node_key, new_validator):
    voters = ValidatorElection.recipients(b)
    return ValidatorElection.generate([node_key.public_key], voters,
                                      new_validator,
                                      None).sign([node_key.private_key])
Ejemplo n.º 27
0
def test_upsert_validator_valid_election(b_mock, new_validator, node_key):
    voters = ValidatorElection.recipients(b_mock)
    election = ValidatorElection.generate([node_key.public_key], voters,
                                          new_validator,
                                          None).sign([node_key.private_key])
    assert election.validate(b_mock)
Ejemplo n.º 28
0
def fixed_seed_election(b_mock, node_key, new_validator):
    voters = ValidatorElection.recipients(b_mock)
    return ValidatorElection.generate([node_key.public_key], voters,
                                      new_validator,
                                      None).sign([node_key.private_key])
Ejemplo n.º 29
0
def fixed_seed_election(b_mock, node_key, new_validator):
    voters = ValidatorElection.recipients(b_mock)
    return ValidatorElection.generate([node_key.public_key],
                                      voters,
                                      new_validator, None).sign([node_key.private_key])
Ejemplo n.º 30
0
def valid_upsert_validator_election_b(b, node_key, new_validator):
    voters = ValidatorElection.recipients(b)
    return ValidatorElection.generate([node_key.public_key],
                                      voters,
                                      new_validator, None).sign([node_key.private_key])
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 ValidatorElection.has_concluded(b, election.id, [tx_vote0])
    assert not ValidatorElection.has_concluded(b, election.id,
                                               [tx_vote0, tx_vote1])
    assert ValidatorElection.has_concluded(b, election.id,
                                           [tx_vote0, tx_vote1, tx_vote2])

    assert not ValidatorElection.approved_update(b, 4, [tx_vote0])
    assert not ValidatorElection.approved_update(b, 4, [tx_vote0, tx_vote1])

    update = ValidatorElection.approved_update(b, 4,
                                               [tx_vote0, tx_vote1, tx_vote2])
    assert update
    update_public_key = codecs.encode(update.pub_key.data,
                                      'base64').decode().rstrip('\n')
    assert update_public_key == public_key64

    b.store_bulk_transactions([tx_vote0, tx_vote1])

    update = ValidatorElection.approved_update(b, 4, [tx_vote2])
    assert update
    update_public_key = codecs.encode(update.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 = ValidatorElection.approved_update(b, 9, [tx_vote2])
    if update:
        update_public_key = codecs.encode(update.pub_key.data,
                                          'base64').decode().rstrip('\n')
    assert update
    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