diff --git a/bigchaindb/util.py b/bigchaindb/util.py index 62454be0..c469ec6b 100644 --- a/bigchaindb/util.py +++ b/bigchaindb/util.py @@ -220,15 +220,14 @@ def create_tx(current_owners, new_owners, inputs, operation, payload=None): inputs = [inputs] # handle payload - data = None - if isinstance(payload, (dict, type(None))): - data = { - 'uuid': str(uuid.uuid4()), - 'payload': payload - } - else: + if payload is not None and not isinstance(payload, dict): raise TypeError('`payload` must be an dict instance or None') + data = { + 'uuid': str(uuid.uuid4()), + 'payload': payload + } + # handle inputs fulfillments = [] @@ -397,13 +396,15 @@ def fulfill_threshold_signature_fulfillment(fulfillment, parsed_fulfillment, ful try: subfulfillment = parsed_fulfillment_copy.get_subcondition_from_vk(current_owner)[0] except IndexError: - exceptions.KeypairMismatchException('Public key {} cannot be found in the fulfillment' - .format(current_owner)) + raise exceptions.KeypairMismatchException( + 'Public key {} cannot be found in the fulfillment'.format(current_owner)) try: - subfulfillment.sign(serialize(fulfillment_message), key_pairs[current_owner]) + private_key = key_pairs[current_owner] except KeyError: - raise exceptions.KeypairMismatchException('Public key {} is not a pair to any of the private keys' - .format(current_owner)) + raise exceptions.KeypairMismatchException( + 'Public key {} is not a pair to any of the private keys'.format(current_owner)) + + subfulfillment.sign(serialize(fulfillment_message), private_key) parsed_fulfillment.add_subfulfillment(subfulfillment) return parsed_fulfillment diff --git a/tests/test_util.py b/tests/test_util.py index aad1af40..a8bb21ec 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -1,6 +1,9 @@ -from unittest.mock import patch, call -import pytest import queue +from unittest.mock import patch, call + +import pytest + +from cryptoconditions import ThresholdSha256Fulfillment @pytest.fixture @@ -142,3 +145,68 @@ def test_process_group_instantiates_and_start_processes(mock_process): for process in pg.processes: process.start.assert_called_with() + +def test_create_tx_with_empty_inputs(): + from bigchaindb.util import create_tx + tx = create_tx(None, None, [], None) + assert 'id' in tx + assert 'transaction' in tx + assert 'version' in tx + assert 'fulfillments' in tx['transaction'] + assert 'conditions' in tx['transaction'] + assert 'operation' in tx['transaction'] + assert 'timestamp' in tx['transaction'] + assert 'data' in tx['transaction'] + assert len(tx['transaction']['fulfillments']) == 1 + assert tx['transaction']['fulfillments'][0] == { + 'current_owners': [], 'input': None, 'fulfillment': None, 'fid': 0} + + +def test_fulfill_threshold_signature_fulfillment_pubkey_notfound(monkeypatch): + from bigchaindb.exceptions import KeypairMismatchException + from bigchaindb.util import fulfill_threshold_signature_fulfillment + monkeypatch.setattr( + ThresholdSha256Fulfillment, + 'get_subcondition_from_vk', + lambda x, y: [] + ) + fulfillment = {'current_owners': (None,)} + parsed_fulfillment = ThresholdSha256Fulfillment() + with pytest.raises(KeypairMismatchException): + fulfill_threshold_signature_fulfillment( + fulfillment, parsed_fulfillment, None, None) + + +def test_fulfill_threshold_signature_fulfillment_wrong_privkeys(monkeypatch): + from bigchaindb.exceptions import KeypairMismatchException + from bigchaindb.util import fulfill_threshold_signature_fulfillment + monkeypatch.setattr( + ThresholdSha256Fulfillment, + 'get_subcondition_from_vk', + lambda x, y: (None,) + ) + fulfillment = {'current_owners': ('alice-pub-key',)} + parsed_fulfillment = ThresholdSha256Fulfillment() + with pytest.raises(KeypairMismatchException): + fulfill_threshold_signature_fulfillment( + fulfillment, parsed_fulfillment, None, {}) + + +def test_check_hash_and_signature_invalid_hash(monkeypatch): + from bigchaindb.exceptions import InvalidHash + from bigchaindb.util import check_hash_and_signature + transaction = {'id': 'txid'} + monkeypatch.setattr('bigchaindb.util.get_hash_data', lambda tx: 'txhash') + with pytest.raises(InvalidHash): + check_hash_and_signature(transaction) + + +def test_check_hash_and_signature_invalid_signature(monkeypatch): + from bigchaindb.exceptions import InvalidSignature + from bigchaindb.util import check_hash_and_signature + transaction = {'id': 'txid'} + monkeypatch.setattr('bigchaindb.util.get_hash_data', lambda tx: 'txid') + monkeypatch.setattr( + 'bigchaindb.util.validate_fulfillments', lambda tx: False) + with pytest.raises(InvalidSignature): + check_hash_and_signature(transaction)