def test_vote_no_double_inclusion(b):
    from bigchaindb.pipelines import vote

    tx = dummy_tx(b)
    block = b.create_block([tx])
    r = vote.Vote().validate_tx(tx.to_dict(), block.id, 1)
    assert r == (True, block.id, 1)

    b.write_block(block)
    r = vote.Vote().validate_tx(tx.to_dict(), 'other_block_id', 1)
    assert r == (False, 'other_block_id', 1)
def test_valid_block_voting_sequential(b, genesis_block, monkeypatch):
    from bigchaindb.backend import query
    from bigchaindb.common import crypto, utils
    from bigchaindb.pipelines import vote

    monkeypatch.setattr('time.time', lambda: 1111111111)
    vote_obj = vote.Vote()
    block = dummy_block(b).to_dict()
    txs = block['block']['transactions']

    for tx, block_id, num_tx in vote_obj.ungroup(block['id'], txs):
        last_vote = vote_obj.vote(*vote_obj.validate_tx(tx, block_id, num_tx))

    vote_obj.write_vote(*last_vote)
    vote_rs = query.get_votes_by_block_id_and_voter(b.connection, block_id,
                                                    b.me)
    vote_doc = vote_rs.next()

    assert vote_doc['vote'] == {
        'voting_for_block': block['id'],
        'previous_block': genesis_block.id,
        'is_block_valid': True,
        'invalid_reason': None,
        'timestamp': '1111111111'
    }

    serialized_vote = utils.serialize(vote_doc['vote']).encode()
    assert vote_doc['node_pubkey'] == b.me
    assert crypto.PublicKey(b.me).verify(serialized_vote,
                                         vote_doc['signature']) is True
def test_vote_ungroup_returns_a_set_of_results(b):
    from bigchaindb.pipelines import vote

    block = dummy_block(b)
    vote_obj = vote.Vote()
    txs = list(vote_obj.ungroup(block.id, block.transactions))

    assert len(txs) == 10
def test_duplicate_transaction(signed_create_tx):
    from bigchaindb.pipelines import vote

    with patch('bigchaindb.core.Bigchain.is_new_transaction') as is_new:
        is_new.return_value = False
        res = vote.Vote().validate_tx(signed_create_tx.to_dict(), 'a', 1)
    assert res == (False, 'a', 1)
    assert is_new.call_count == 1
def test_validate_block_with_duplicated_transactions(b):
    from bigchaindb.pipelines import vote

    tx = dummy_tx(b)
    block = b.create_block([tx, tx]).to_dict()

    vote_obj = vote.Vote()
    block_id, invalid_dummy_tx = vote_obj.validate_block(block)
    assert invalid_dummy_tx == [vote_obj.invalid_dummy_tx]
def test_validate_block_with_invalid_signature(b):
    from bigchaindb.pipelines import vote

    tx = dummy_tx(b)
    block = b.create_block([tx]).to_dict()
    block['signature'] = 'an invalid signature'

    vote_obj = vote.Vote()
    block_id, invalid_dummy_tx = vote_obj.validate_block(block)
    assert block_id == block['id']
    assert invalid_dummy_tx == [vote_obj.invalid_dummy_tx]
def test_vote_validate_block(b):
    from bigchaindb.pipelines import vote

    tx = dummy_tx(b)
    block = b.create_block([tx])
    block_dict = decouple_assets(b, block)

    vote_obj = vote.Vote()
    validation = vote_obj.validate_block(block_dict)
    assert validation[0] == block.id
    for tx1, tx2 in zip(validation[1], block.transactions):
        assert tx1 == tx2.to_dict()

    block = b.create_block([tx])
    # NOTE: Setting a blocks signature to `None` invalidates it.
    block.signature = None

    vote_obj = vote.Vote()
    validation = vote_obj.validate_block(block.to_dict())
    assert validation[0] == block.id
    for tx1, tx2 in zip(validation[1], [vote_obj.invalid_dummy_tx]):
        assert tx1 == tx2
def test_vote_accumulates_transactions(b):
    from bigchaindb.pipelines import vote

    vote_obj = vote.Vote()

    tx = dummy_tx(b)

    validation = vote_obj.validate_tx(tx.to_dict(), 123, 1)
    assert validation == (True, 123, 1)

    tx.inputs[0].fulfillment.signature = 64 * b'z'
    validation = vote_obj.validate_tx(tx.to_dict(), 456, 10)
    assert validation == (False, 456, 10)
def test_vote_validate_transaction(b):
    from bigchaindb.pipelines import vote
    from bigchaindb.common.exceptions import ValidationError

    tx = dummy_tx(b).to_dict()
    vote_obj = vote.Vote()
    validation = vote_obj.validate_tx(tx, 123, 1)
    assert validation == (True, 123, 1)

    with patch('bigchaindb.models.Transaction.validate') as validate:
        # Assert that validationerror gets caught
        validate.side_effect = ValidationError()
        validation = vote_obj.validate_tx(tx, 456, 10)
        assert validation == (False, 456, 10)

        # Assert that another error doesnt
        validate.side_effect = IOError()
        with pytest.raises(IOError):
            validation = vote_obj.validate_tx(tx, 456, 10)