mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
443 lines
15 KiB
Python
443 lines
15 KiB
Python
from pytest import raises
|
|
|
|
|
|
def test_fulfillment_serialization(ffill_uri, user_pub):
|
|
from bigchaindb_common.transaction import Fulfillment
|
|
from cryptoconditions import Fulfillment as CCFulfillment
|
|
|
|
expected = {
|
|
'owners_before': [user_pub],
|
|
'fulfillment': ffill_uri,
|
|
'input': None,
|
|
}
|
|
ffill = Fulfillment(CCFulfillment.from_uri(ffill_uri), [user_pub])
|
|
assert ffill.to_dict() == expected
|
|
|
|
|
|
def test_fulfillment_deserialization_with_uri(ffill_uri, user_pub):
|
|
from bigchaindb_common.transaction import Fulfillment
|
|
from cryptoconditions import Fulfillment as CCFulfillment
|
|
|
|
expected = Fulfillment(CCFulfillment.from_uri(ffill_uri), [user_pub])
|
|
ffill = {
|
|
'owners_before': [user_pub],
|
|
'fulfillment': ffill_uri,
|
|
'input': None,
|
|
}
|
|
ffill = Fulfillment.from_dict(ffill)
|
|
|
|
assert ffill == expected
|
|
|
|
|
|
def test_fulfillment_deserialization_with_dict(user_pub):
|
|
from bigchaindb_common.transaction import Fulfillment
|
|
|
|
expected = Fulfillment(None, [user_pub])
|
|
|
|
ffill = {
|
|
'owners_before': [user_pub],
|
|
'fulfillment': None,
|
|
'input': None,
|
|
}
|
|
ffill = Fulfillment.from_dict(ffill)
|
|
|
|
assert ffill == expected
|
|
|
|
|
|
def test_condition_serialization(user_Ed25519, user_pub):
|
|
from bigchaindb_common.transaction import Condition
|
|
|
|
expected = {
|
|
'condition': {
|
|
'uri': user_Ed25519.condition_uri,
|
|
'details': user_Ed25519.to_dict(),
|
|
},
|
|
'owners_after': [user_pub],
|
|
}
|
|
|
|
cond = Condition(user_Ed25519, [user_pub])
|
|
|
|
assert cond.to_dict() == expected
|
|
|
|
|
|
def test_condition_deserialization(user_Ed25519, user_pub):
|
|
from bigchaindb_common.transaction import Condition
|
|
|
|
expected = Condition(user_Ed25519, [user_pub])
|
|
cond = {
|
|
'condition': {
|
|
'uri': user_Ed25519.condition_uri,
|
|
'details': user_Ed25519.to_dict()
|
|
},
|
|
'owners_after': [user_pub],
|
|
}
|
|
cond = Condition.from_dict(cond)
|
|
|
|
assert cond == expected
|
|
|
|
|
|
def test_invalid_condition_initialization(cond_uri, user_pub):
|
|
from bigchaindb_common.transaction import Condition
|
|
|
|
with raises(TypeError):
|
|
Condition(cond_uri, user_pub)
|
|
|
|
|
|
def test_transaction_serialization(user_ffill, user_cond):
|
|
from bigchaindb_common.transaction import Transaction
|
|
|
|
tx_id = 'l0l'
|
|
timestamp = '66666666666'
|
|
|
|
expected = {
|
|
'id': tx_id,
|
|
'version': Transaction.VERSION,
|
|
'transaction': {
|
|
# NOTE: This test assumes that Fulfillments and Conditions can successfully be serialized
|
|
'fulfillments': [user_ffill.to_dict(0)],
|
|
'conditions': [user_cond.to_dict(0)],
|
|
'operation': Transaction.CREATE,
|
|
'timestamp': timestamp,
|
|
'data': None,
|
|
}
|
|
}
|
|
|
|
tx_dict = Transaction(Transaction.CREATE, [user_ffill], [user_cond]).to_dict()
|
|
tx_dict['id'] = tx_id
|
|
tx_dict['transaction']['timestamp'] = timestamp
|
|
|
|
assert tx_dict == expected
|
|
|
|
|
|
def test_transaction_deserialization(user_ffill, user_cond):
|
|
from bigchaindb_common.transaction import Transaction
|
|
|
|
timestamp = '66666666666'
|
|
|
|
expected = Transaction(Transaction.CREATE, [user_ffill], [user_cond], None, timestamp,
|
|
Transaction.VERSION)
|
|
|
|
tx = {
|
|
'version': Transaction.VERSION,
|
|
'transaction': {
|
|
# NOTE: This test assumes that Fulfillments and Conditions can successfully be serialized
|
|
'fulfillments': [user_ffill.to_dict()],
|
|
'conditions': [user_cond.to_dict()],
|
|
'operation': Transaction.CREATE,
|
|
'timestamp': timestamp,
|
|
'data': None,
|
|
}
|
|
}
|
|
tx['id'] = Transaction._to_hash(Transaction._to_str(Transaction._remove_signatures(tx)))
|
|
tx = Transaction.from_dict(tx)
|
|
|
|
assert tx == expected
|
|
|
|
|
|
def test_tx_serialization_with_incorrect_hash(utx):
|
|
from bigchaindb_common.transaction import Transaction
|
|
from bigchaindb_common.exceptions import InvalidHash
|
|
|
|
utx_dict = utx.to_dict()
|
|
utx_dict['id'] = 'abc'
|
|
with raises(InvalidHash):
|
|
Transaction.from_dict(utx_dict)
|
|
utx_dict.pop('id')
|
|
with raises(InvalidHash):
|
|
Transaction.from_dict(utx_dict)
|
|
utx_dict['id'] = []
|
|
with raises(InvalidHash):
|
|
Transaction.from_dict(utx_dict)
|
|
|
|
|
|
def test_invalid_tx_initialization():
|
|
from bigchaindb_common.transaction import Transaction
|
|
|
|
wrong_data_type = {'payload': 'a totally wrong datatype'}
|
|
with raises(TypeError):
|
|
Transaction(Transaction.CREATE, wrong_data_type)
|
|
with raises(TypeError):
|
|
Transaction(Transaction.CREATE, [], wrong_data_type)
|
|
with raises(TypeError):
|
|
Transaction(Transaction.CREATE, [], [], wrong_data_type)
|
|
with raises(TypeError):
|
|
Transaction('RANSFER', [], [])
|
|
|
|
|
|
def test_invalid_fulfillment_initialization(user_ffill, user_pub):
|
|
from bigchaindb_common.transaction import Fulfillment
|
|
|
|
with raises(TypeError):
|
|
Fulfillment(user_ffill, user_pub)
|
|
with raises(TypeError):
|
|
Fulfillment(user_ffill, [], tx_input='somethingthatiswrong')
|
|
|
|
|
|
def test_invalid_data_initialization():
|
|
from bigchaindb_common.transaction import Data
|
|
|
|
with raises(TypeError):
|
|
Data([])
|
|
|
|
|
|
def test_data_serialization(payload, payload_id):
|
|
from bigchaindb_common.transaction import Data
|
|
|
|
expected = {
|
|
'payload': payload,
|
|
'uuid': payload_id
|
|
}
|
|
data = Data(payload, payload_id)
|
|
|
|
assert data.to_dict() == expected
|
|
|
|
|
|
def test_data_deserialization(payload, payload_id):
|
|
from bigchaindb_common.transaction import Data
|
|
|
|
expected = Data(payload, payload_id)
|
|
data = Data.from_dict({'payload': payload, 'uuid': payload_id})
|
|
|
|
assert data == expected
|
|
|
|
|
|
def test_transaction_link_serialization():
|
|
from bigchaindb_common.transaction import TransactionLink
|
|
|
|
tx_id = 'a transaction id'
|
|
expected = {
|
|
'txid': tx_id,
|
|
'cid': 0,
|
|
}
|
|
tx_link = TransactionLink(tx_id, 0)
|
|
|
|
assert tx_link.to_dict() == expected
|
|
|
|
|
|
def test_transaction_link_serialization_with_empty_payload():
|
|
from bigchaindb_common.transaction import TransactionLink
|
|
|
|
expected = None
|
|
tx_link = TransactionLink()
|
|
|
|
assert tx_link.to_dict() == expected
|
|
|
|
|
|
def test_transaction_link_deserialization():
|
|
from bigchaindb_common.transaction import TransactionLink
|
|
|
|
tx_id = 'a transaction id'
|
|
expected = TransactionLink(tx_id, 0)
|
|
tx_link = {
|
|
'txid': tx_id,
|
|
'cid': 0,
|
|
}
|
|
tx_link = TransactionLink.from_dict(tx_link)
|
|
|
|
assert tx_link == expected
|
|
|
|
|
|
def test_transaction_link_deserialization_with_empty_payload():
|
|
from bigchaindb_common.transaction import TransactionLink
|
|
|
|
expected = TransactionLink()
|
|
tx_link = TransactionLink.from_dict(None)
|
|
|
|
assert tx_link == expected
|
|
|
|
|
|
def test_add_fulfillment_to_tx(user_ffill):
|
|
from bigchaindb_common.transaction import Transaction
|
|
|
|
tx = Transaction(Transaction.CREATE, [], [])
|
|
tx.add_fulfillment(user_ffill)
|
|
|
|
assert len(tx.fulfillments) == 1
|
|
|
|
|
|
def test_add_fulfillment_to_tx_with_invalid_parameters():
|
|
from bigchaindb_common.transaction import Transaction
|
|
|
|
tx = Transaction(Transaction.CREATE)
|
|
with raises(TypeError):
|
|
tx.add_fulfillment('somewronginput')
|
|
|
|
|
|
def test_add_condition_to_tx(user_cond):
|
|
from bigchaindb_common.transaction import Transaction
|
|
|
|
tx = Transaction(Transaction.CREATE)
|
|
tx.add_condition(user_cond)
|
|
|
|
assert len(tx.conditions) == 1
|
|
|
|
|
|
def test_add_condition_to_tx_with_invalid_parameters():
|
|
from bigchaindb_common.transaction import Transaction
|
|
|
|
tx = Transaction(Transaction.CREATE, [], [])
|
|
with raises(TypeError):
|
|
tx.add_condition('somewronginput')
|
|
|
|
|
|
def test_sign_with_invalid_parameters(utx, user_priv):
|
|
with raises(TypeError):
|
|
utx.sign(None)
|
|
with raises(TypeError):
|
|
utx.sign(user_priv)
|
|
|
|
|
|
def test_validate_tx_simple_create_signature(user_ffill, user_cond, user_priv):
|
|
from copy import deepcopy
|
|
from bigchaindb_common.crypto import SigningKey
|
|
from bigchaindb_common.transaction import Transaction
|
|
|
|
tx = Transaction(Transaction.CREATE, [user_ffill], [user_cond])
|
|
expected = deepcopy(user_cond)
|
|
expected.fulfillment.sign(str(tx), SigningKey(user_priv))
|
|
tx.sign([user_priv])
|
|
|
|
assert tx.fulfillments[0].to_dict()['fulfillment'] == expected.fulfillment.serialize_uri()
|
|
assert tx.fulfillments_valid() is True
|
|
|
|
|
|
def test_invoke_simple_signature_fulfillment_with_invalid_parameters(utx, user_ffill):
|
|
from bigchaindb_common.exceptions import KeypairMismatchException
|
|
|
|
with raises(KeypairMismatchException):
|
|
utx._sign_simple_signature_fulfillment(user_ffill,
|
|
0,
|
|
'somemessage',
|
|
{'wrong_pub_key': 'wrong_priv_key'})
|
|
|
|
|
|
def test_invoke_threshold_signature_fulfillment_with_invalid_parameters(utx,
|
|
user_user2_threshold_ffill,
|
|
user3_pub,
|
|
user3_priv):
|
|
from bigchaindb_common.exceptions import KeypairMismatchException
|
|
|
|
with raises(KeypairMismatchException):
|
|
utx._sign_threshold_signature_fulfillment(user_user2_threshold_ffill,
|
|
0,
|
|
'somemessage',
|
|
{user3_pub: user3_priv})
|
|
with raises(KeypairMismatchException):
|
|
user_user2_threshold_ffill.owners_before = ['somewrongvalue']
|
|
utx._sign_threshold_signature_fulfillment(user_user2_threshold_ffill,
|
|
0,
|
|
'somemessage',
|
|
None)
|
|
|
|
|
|
def test_validate_fulfillment_with_invalid_parameters(utx):
|
|
from bigchaindb_common.transaction import Transaction
|
|
input_conditions = [cond.fulfillment.condition_uri for cond
|
|
in utx.conditions]
|
|
tx_serialized = Transaction._to_str(Transaction._remove_signatures(utx.to_dict()))
|
|
assert utx._fulfillment_valid(utx.fulfillments[0],
|
|
tx_serialized,
|
|
input_conditions) == False
|
|
|
|
|
|
def test_validate_multiple_fulfillments(user_ffill, user_cond, user_priv):
|
|
from copy import deepcopy
|
|
|
|
from bigchaindb_common.crypto import SigningKey
|
|
from bigchaindb_common.transaction import Transaction
|
|
|
|
tx = Transaction(Transaction.CREATE,
|
|
[user_ffill, deepcopy(user_ffill)],
|
|
[user_ffill, deepcopy(user_cond)])
|
|
|
|
expected_first = deepcopy(tx)
|
|
expected_second = deepcopy(tx)
|
|
expected_first.fulfillments = [expected_first.fulfillments[0]]
|
|
expected_first.conditions = [expected_first.conditions[0]]
|
|
expected_second.fulfillments = [expected_second.fulfillments[1]]
|
|
expected_second.conditions = [expected_second.conditions[1]]
|
|
|
|
expected_first.fulfillments[0].fulfillment.sign(str(expected_first), SigningKey(user_priv))
|
|
expected_second.fulfillments[0].fulfillment.sign(str(expected_second), SigningKey(user_priv))
|
|
tx.sign([user_priv])
|
|
|
|
assert tx.fulfillments[0].to_dict()['fulfillment'] == expected_first.fulfillments[0].fulfillment.serialize_uri()
|
|
assert tx.fulfillments[1].to_dict()['fulfillment'] == expected_second.fulfillments[0].fulfillment.serialize_uri()
|
|
assert tx.fulfillments_valid() is True
|
|
|
|
|
|
def test_validate_tx_threshold_create_signature(user_user2_threshold_ffill,
|
|
user_user2_threshold_cond,
|
|
user_pub,
|
|
user2_pub,
|
|
user_priv,
|
|
user2_priv):
|
|
from copy import deepcopy
|
|
|
|
from bigchaindb_common.crypto import SigningKey
|
|
from bigchaindb_common.transaction import Transaction
|
|
|
|
tx = Transaction(Transaction.CREATE, [user_user2_threshold_ffill], [user_user2_threshold_cond])
|
|
expected = deepcopy(user_user2_threshold_cond)
|
|
expected.fulfillment.subconditions[0]['body'].sign(str(tx), SigningKey(user_priv))
|
|
expected.fulfillment.subconditions[1]['body'].sign(str(tx), SigningKey(user2_priv))
|
|
tx.sign([user_priv, user2_priv])
|
|
|
|
assert tx.fulfillments[0].to_dict()['fulfillment'] == expected.fulfillment.serialize_uri()
|
|
assert tx.fulfillments_valid() is True
|
|
|
|
|
|
def test_multiple_fulfillment_validation_of_transfer_tx(user_ffill, user_cond,
|
|
user_priv, user2_pub,
|
|
user2_priv, user3_pub,
|
|
user3_priv):
|
|
from copy import deepcopy
|
|
from bigchaindb_common.transaction import (Transaction, TransactionLink,
|
|
Fulfillment, Condition)
|
|
from cryptoconditions import Ed25519Fulfillment
|
|
|
|
tx = Transaction(Transaction.CREATE,
|
|
[user_ffill, deepcopy(user_ffill)],
|
|
[user_cond, deepcopy(user_cond)])
|
|
tx.sign([user_priv])
|
|
|
|
fulfillments = [Fulfillment(cond.fulfillment, cond.owners_after,
|
|
TransactionLink(tx.id, index))
|
|
for index, cond in enumerate(tx.conditions)]
|
|
conditions = [Condition(Ed25519Fulfillment(public_key=user3_pub), [user3_pub]),
|
|
Condition(Ed25519Fulfillment(public_key=user3_pub), [user3_pub])]
|
|
transfer_tx = Transaction('TRANSFER', fulfillments, conditions)
|
|
|
|
transfer_tx = transfer_tx.sign([user_priv])
|
|
|
|
assert transfer_tx.fulfillments_valid(tx.conditions) is True
|
|
|
|
|
|
def test_validate_fulfillments_of_transfer_tx_with_invalid_parameters(transfer_tx,
|
|
cond_uri,
|
|
utx,
|
|
user2_pub,
|
|
user_priv):
|
|
from bigchaindb_common.transaction import Condition
|
|
from cryptoconditions import Ed25519Fulfillment
|
|
|
|
assert transfer_tx.fulfillments_valid([Condition(Ed25519Fulfillment.from_uri('cf:0:'),
|
|
['invalid'])]) is False
|
|
invalid_cond = utx.conditions[0]
|
|
invalid_cond.owners_after = 'invalid'
|
|
assert transfer_tx.fulfillments_valid([invalid_cond]) is True
|
|
|
|
with raises(TypeError):
|
|
assert transfer_tx.fulfillments_valid(None) is False
|
|
with raises(AttributeError):
|
|
transfer_tx.fulfillments_valid('not a list')
|
|
with raises(ValueError):
|
|
transfer_tx.fulfillments_valid([])
|
|
with raises(TypeError):
|
|
transfer_tx.operation = "Operation that doesn't exist"
|
|
transfer_tx.fulfillments_valid([utx.conditions[0]])
|
|
with raises(ValueError):
|
|
tx = utx.sign([user_priv])
|
|
tx.conditions = []
|
|
tx.fulfillments_valid()
|