mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Integrate cryptoconditions version 02
This commit is contained in:
parent
a175f371b0
commit
02fe712c34
@ -7,6 +7,6 @@ pip install --upgrade pip
|
||||
if [[ -n ${TOXENV} ]]; then
|
||||
pip install --upgrade tox
|
||||
else
|
||||
pip install -e .[test]
|
||||
pip install .[test]
|
||||
pip install --upgrade codecov
|
||||
fi
|
||||
|
@ -154,7 +154,7 @@ definitions:
|
||||
additionalProperties: true
|
||||
uri:
|
||||
type: string
|
||||
pattern: "^cc:([1-9a-f][0-9a-f]{0,3}|0):[1-9a-f][0-9a-f]{0,15}:[a-zA-Z0-9_-]{0,86}:([1-9][0-9]{0,17}|0)$"
|
||||
pattern: "^ni:///sha-256;([a-zA-Z0-9_-]{0,86})?(.+)$"
|
||||
public_keys:
|
||||
"$ref": "#/definitions/public_keys"
|
||||
description: |
|
||||
@ -195,7 +195,7 @@ definitions:
|
||||
that satisfies the condition of a previous output to prove that the
|
||||
creator(s) of this transaction have control over the listed asset.
|
||||
- type: string
|
||||
pattern: "^cf:([1-9a-f][0-9a-f]{0,3}|0):[a-zA-Z0-9_-]*$"
|
||||
pattern: "^[a-zA-Z0-9_-]*$"
|
||||
fulfills:
|
||||
anyOf:
|
||||
- type: 'object'
|
||||
|
@ -1,15 +1,16 @@
|
||||
from copy import deepcopy
|
||||
from functools import reduce
|
||||
|
||||
from cryptoconditions import (Fulfillment, ThresholdSha256Fulfillment,
|
||||
Ed25519Fulfillment)
|
||||
from cryptoconditions.exceptions import ParsingError
|
||||
import base58
|
||||
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256
|
||||
from cryptoconditions.exceptions import (
|
||||
ParsingError, ASN1DecodeError, ASN1EncodeError)
|
||||
|
||||
from bigchaindb.common.crypto import PrivateKey, hash_data
|
||||
from bigchaindb.common.exceptions import (KeypairMismatchException,
|
||||
InvalidHash, InvalidSignature,
|
||||
AmountError, AssetIdMismatch)
|
||||
from bigchaindb.common.utils import serialize, gen_timestamp
|
||||
from bigchaindb.common.utils import serialize
|
||||
import bigchaindb.version
|
||||
|
||||
|
||||
@ -65,7 +66,7 @@ class Input(object):
|
||||
"""
|
||||
try:
|
||||
fulfillment = self.fulfillment.serialize_uri()
|
||||
except (TypeError, AttributeError):
|
||||
except (TypeError, AttributeError, ASN1EncodeError):
|
||||
# NOTE: When a non-signed transaction is casted to a dict,
|
||||
# `self.inputs` value is lost, as in the node's
|
||||
# transaction model that is saved to the database, does not
|
||||
@ -114,15 +115,18 @@ class Input(object):
|
||||
Raises:
|
||||
InvalidSignature: If an Input's URI couldn't be parsed.
|
||||
"""
|
||||
try:
|
||||
fulfillment = Fulfillment.from_uri(data['fulfillment'])
|
||||
except ValueError:
|
||||
# TODO FOR CC: Throw an `InvalidSignature` error in this case.
|
||||
raise InvalidSignature("Fulfillment URI couldn't been parsed")
|
||||
except TypeError:
|
||||
# NOTE: See comment about this special case in
|
||||
# `Input.to_dict`
|
||||
fulfillment = Fulfillment.from_dict(data['fulfillment'])
|
||||
fulfillment = data['fulfillment']
|
||||
if not isinstance(fulfillment, Fulfillment):
|
||||
try:
|
||||
fulfillment = Fulfillment.from_uri(data['fulfillment'])
|
||||
except ASN1DecodeError:
|
||||
# TODO Remove as it is legacy code, and simply fall back on
|
||||
# ASN1DecodeError
|
||||
raise InvalidSignature("Fulfillment URI couldn't been parsed")
|
||||
except TypeError:
|
||||
# NOTE: See comment about this special case in
|
||||
# `Input.to_dict`
|
||||
fulfillment = Fulfillment.from_dict(data['fulfillment'])
|
||||
fulfills = TransactionLink.from_dict(data['fulfills'])
|
||||
return cls(fulfillment, data['owners_before'], fulfills)
|
||||
|
||||
@ -310,13 +314,14 @@ class Output(object):
|
||||
raise ValueError('`public_keys` needs to contain at least one'
|
||||
'owner')
|
||||
elif len(public_keys) == 1 and not isinstance(public_keys[0], list):
|
||||
try:
|
||||
ffill = Ed25519Fulfillment(public_key=public_keys[0])
|
||||
except TypeError:
|
||||
if isinstance(public_keys[0], Fulfillment):
|
||||
ffill = public_keys[0]
|
||||
else:
|
||||
ffill = Ed25519Sha256(
|
||||
public_key=base58.b58decode(public_keys[0]))
|
||||
return cls(ffill, public_keys, amount=amount)
|
||||
else:
|
||||
initial_cond = ThresholdSha256Fulfillment(threshold=threshold)
|
||||
initial_cond = ThresholdSha256(threshold=threshold)
|
||||
threshold_cond = reduce(cls._gen_condition, public_keys,
|
||||
initial_cond)
|
||||
return cls(threshold_cond, public_keys, amount=amount)
|
||||
@ -331,13 +336,13 @@ class Output(object):
|
||||
:meth:`~.Output.generate`.
|
||||
|
||||
Args:
|
||||
initial (:class:`cryptoconditions.ThresholdSha256Fulfillment`):
|
||||
initial (:class:`cryptoconditions.ThresholdSha256`):
|
||||
A Condition representing the overall root.
|
||||
new_public_keys (:obj:`list` of :obj:`str`|str): A list of new
|
||||
owners or a single new owner.
|
||||
|
||||
Returns:
|
||||
:class:`cryptoconditions.ThresholdSha256Fulfillment`:
|
||||
:class:`cryptoconditions.ThresholdSha256`:
|
||||
"""
|
||||
try:
|
||||
threshold = len(new_public_keys)
|
||||
@ -345,7 +350,7 @@ class Output(object):
|
||||
threshold = None
|
||||
|
||||
if isinstance(new_public_keys, list) and len(new_public_keys) > 1:
|
||||
ffill = ThresholdSha256Fulfillment(threshold=threshold)
|
||||
ffill = ThresholdSha256(threshold=threshold)
|
||||
reduce(cls._gen_condition, new_public_keys, ffill)
|
||||
elif isinstance(new_public_keys, list) and len(new_public_keys) <= 1:
|
||||
raise ValueError('Sublist cannot contain single owner')
|
||||
@ -354,16 +359,17 @@ class Output(object):
|
||||
new_public_keys = new_public_keys.pop()
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
ffill = Ed25519Fulfillment(public_key=new_public_keys)
|
||||
except TypeError:
|
||||
# NOTE: Instead of submitting base58 encoded addresses, a user
|
||||
# of this class can also submit fully instantiated
|
||||
# Cryptoconditions. In the case of casting
|
||||
# `new_public_keys` to a Ed25519Fulfillment with the
|
||||
# result of a `TypeError`, we're assuming that
|
||||
# `new_public_keys` is a Cryptocondition then.
|
||||
# NOTE: Instead of submitting base58 encoded addresses, a user
|
||||
# of this class can also submit fully instantiated
|
||||
# Cryptoconditions. In the case of casting
|
||||
# `new_public_keys` to a Ed25519Fulfillment with the
|
||||
# result of a `TypeError`, we're assuming that
|
||||
# `new_public_keys` is a Cryptocondition then.
|
||||
if isinstance(new_public_keys, Fulfillment):
|
||||
ffill = new_public_keys
|
||||
else:
|
||||
ffill = Ed25519Sha256(
|
||||
public_key=base58.b58decode(new_public_keys))
|
||||
initial.add_subfulfillment(ffill)
|
||||
return initial
|
||||
|
||||
@ -661,7 +667,7 @@ class Transaction(object):
|
||||
This method works only for the following Cryptoconditions
|
||||
currently:
|
||||
- Ed25519Fulfillment
|
||||
- ThresholdSha256Fulfillment
|
||||
- ThresholdSha256
|
||||
Furthermore, note that all keys required to fully sign the
|
||||
Transaction have to be passed to this method. A subset of all
|
||||
will cause this method to fail.
|
||||
@ -712,7 +718,7 @@ class Transaction(object):
|
||||
This method works only for the following Cryptoconditions
|
||||
currently:
|
||||
- Ed25519Fulfillment
|
||||
- ThresholdSha256Fulfillment.
|
||||
- ThresholdSha256.
|
||||
|
||||
Args:
|
||||
input_ (:class:`~bigchaindb.common.transaction.
|
||||
@ -720,10 +726,10 @@ class Transaction(object):
|
||||
message (str): The message to be signed
|
||||
key_pairs (dict): The keys to sign the Transaction with.
|
||||
"""
|
||||
if isinstance(input_.fulfillment, Ed25519Fulfillment):
|
||||
if isinstance(input_.fulfillment, Ed25519Sha256):
|
||||
return cls._sign_simple_signature_fulfillment(input_, message,
|
||||
key_pairs)
|
||||
elif isinstance(input_.fulfillment, ThresholdSha256Fulfillment):
|
||||
elif isinstance(input_.fulfillment, ThresholdSha256):
|
||||
return cls._sign_threshold_signature_fulfillment(input_, message,
|
||||
key_pairs)
|
||||
else:
|
||||
@ -749,7 +755,10 @@ class Transaction(object):
|
||||
try:
|
||||
# cryptoconditions makes no assumptions of the encoding of the
|
||||
# message to sign or verify. It only accepts bytestrings
|
||||
input_.fulfillment.sign(message.encode(), key_pairs[public_key])
|
||||
input_.fulfillment.sign(
|
||||
message.encode(),
|
||||
base58.b58decode(key_pairs[public_key].encode()),
|
||||
)
|
||||
except KeyError:
|
||||
raise KeypairMismatchException('Public key {} is not a pair to '
|
||||
'any of the private keys'
|
||||
@ -758,7 +767,7 @@ class Transaction(object):
|
||||
|
||||
@classmethod
|
||||
def _sign_threshold_signature_fulfillment(cls, input_, message, key_pairs):
|
||||
"""Signs a ThresholdSha256Fulfillment.
|
||||
"""Signs a ThresholdSha256.
|
||||
|
||||
Args:
|
||||
input_ (:class:`~bigchaindb.common.transaction.
|
||||
@ -778,7 +787,8 @@ class Transaction(object):
|
||||
# TODO FOR CC: `get_subcondition` is singular. One would not
|
||||
# expect to get a list back.
|
||||
ccffill = input_.fulfillment
|
||||
subffills = ccffill.get_subcondition_from_vk(owner_before)
|
||||
subffills = ccffill.get_subcondition_from_vk(
|
||||
base58.b58decode(owner_before))
|
||||
if not subffills:
|
||||
raise KeypairMismatchException('Public key {} cannot be found '
|
||||
'in the fulfillment'
|
||||
@ -793,7 +803,7 @@ class Transaction(object):
|
||||
# cryptoconditions makes no assumptions of the encoding of the
|
||||
# message to sign or verify. It only accepts bytestrings
|
||||
for subffill in subffills:
|
||||
subffill.sign(message.encode(), private_key)
|
||||
subffill.sign(message.encode(), base58.b58decode(private_key.encode()))
|
||||
return input_
|
||||
|
||||
def inputs_valid(self, outputs=None):
|
||||
@ -882,7 +892,8 @@ class Transaction(object):
|
||||
ccffill = input_.fulfillment
|
||||
try:
|
||||
parsed_ffill = Fulfillment.from_uri(ccffill.serialize_uri())
|
||||
except (TypeError, ValueError, ParsingError):
|
||||
except (TypeError, ValueError,
|
||||
ParsingError, ASN1DecodeError, ASN1EncodeError):
|
||||
return False
|
||||
|
||||
if operation in (Transaction.CREATE, Transaction.GENESIS):
|
||||
@ -897,8 +908,7 @@ class Transaction(object):
|
||||
|
||||
# cryptoconditions makes no assumptions of the encoding of the
|
||||
# message to sign or verify. It only accepts bytestrings
|
||||
ffill_valid = parsed_ffill.validate(message=tx_serialized.encode(),
|
||||
now=gen_timestamp())
|
||||
ffill_valid = parsed_ffill.validate(message=tx_serialized.encode())
|
||||
return output_valid and ffill_valid
|
||||
|
||||
def to_dict(self):
|
||||
@ -940,7 +950,7 @@ class Transaction(object):
|
||||
tx_dict = deepcopy(tx_dict)
|
||||
for input_ in tx_dict['inputs']:
|
||||
# NOTE: Not all Cryptoconditions return a `signature` key (e.g.
|
||||
# ThresholdSha256Fulfillment), so setting it to `None` in any
|
||||
# ThresholdSha256), so setting it to `None` in any
|
||||
# case could yield incorrect signatures. This is why we only
|
||||
# set it to `None` if it's set in the dict.
|
||||
input_['fulfillment'] = None
|
||||
|
@ -22,6 +22,7 @@ services:
|
||||
- ./setup.cfg:/usr/src/app/setup.cfg
|
||||
- ./pytest.ini:/usr/src/app/pytest.ini
|
||||
- ./tox.ini:/usr/src/app/tox.ini
|
||||
- ../cryptoconditions:/usr/src/app/cryptoconditions
|
||||
environment:
|
||||
BIGCHAINDB_DATABASE_BACKEND: mongodb
|
||||
BIGCHAINDB_DATABASE_HOST: mdb
|
||||
|
4
setup.py
4
setup.py
@ -67,7 +67,7 @@ install_requires = [
|
||||
'rethinkdb~=2.3', # i.e. a version between 2.3 and 3.0
|
||||
'pymongo~=3.4',
|
||||
'pysha3~=1.0.2',
|
||||
'cryptoconditions>=0.5.0',
|
||||
'cryptoconditions>=0.6.0.dev',
|
||||
'python-rapidjson==0.0.11',
|
||||
'logstats>=0.2.1',
|
||||
'flask>=0.10.1',
|
||||
@ -126,7 +126,7 @@ setup(
|
||||
],
|
||||
},
|
||||
install_requires=install_requires,
|
||||
setup_requires=['pytest-runner'],
|
||||
setup_requires=['pytest-runner', 'cryptoconditions'],
|
||||
tests_require=tests_require,
|
||||
extras_require={
|
||||
'test': tests_require,
|
||||
|
@ -1,3 +1,4 @@
|
||||
from base58 import b58decode
|
||||
import pytest
|
||||
|
||||
|
||||
@ -11,8 +12,13 @@ USER3_PRIVATE_KEY = '4rNQFzWQbVwuTiDVxwuFMvLG5zd8AhrQKCtVovBvcYsB'
|
||||
USER3_PUBLIC_KEY = 'Gbrg7JtxdjedQRmr81ZZbh1BozS7fBW88ZyxNDy7WLNC'
|
||||
|
||||
|
||||
CC_FULFILLMENT_URI = 'cf:0:'
|
||||
CC_CONDITION_URI = 'cc:0:3:47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU:0'
|
||||
CC_FULFILLMENT_URI = (
|
||||
'pGSAINdamAGCsQq31Uv-08lkBzoO4XLz2qYjJa8CGmj3B1EagUDlVkMAw2CscpCG4syAboKKh'
|
||||
'Id_Hrjl2XTYc-BlIkkBVV-4ghWQozusxh45cBz5tGvSW_XwWVu-JGVRQUOOehAL'
|
||||
)
|
||||
CC_CONDITION_URI = ('ni:///sha-256;'
|
||||
'eZI5q6j8T_fqv7xMROaei9_tmTMk4S7WR5Kr4onPHV8'
|
||||
'?fpt=ed25519-sha-256&cost=131072')
|
||||
|
||||
ASSET_DEFINITION = {
|
||||
'data': {
|
||||
@ -71,25 +77,25 @@ def cond_uri():
|
||||
|
||||
@pytest.fixture
|
||||
def user_Ed25519(user_pub):
|
||||
from cryptoconditions import Ed25519Fulfillment
|
||||
return Ed25519Fulfillment(public_key=user_pub)
|
||||
from cryptoconditions import Ed25519Sha256
|
||||
return Ed25519Sha256(public_key=b58decode(user_pub))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def user_user2_threshold(user_pub, user2_pub):
|
||||
from cryptoconditions import (ThresholdSha256Fulfillment,
|
||||
Ed25519Fulfillment)
|
||||
from cryptoconditions import ThresholdSha256, Ed25519Sha256
|
||||
user_pub_keys = [user_pub, user2_pub]
|
||||
threshold = ThresholdSha256Fulfillment(threshold=len(user_pub_keys))
|
||||
threshold = ThresholdSha256(threshold=len(user_pub_keys))
|
||||
for user_pub in user_pub_keys:
|
||||
threshold.add_subfulfillment(Ed25519Fulfillment(public_key=user_pub))
|
||||
threshold.add_subfulfillment(
|
||||
Ed25519Sha256(public_key=b58decode(user_pub)))
|
||||
return threshold
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def user2_Ed25519(user2_pub):
|
||||
from cryptoconditions import Ed25519Fulfillment
|
||||
return Ed25519Fulfillment(public_key=user2_pub)
|
||||
from cryptoconditions import Ed25519Sha256
|
||||
return Ed25519Sha256(public_key=b58decode(user2_pub))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -2,7 +2,9 @@
|
||||
These are tests of the API of the Transaction class and associated classes.
|
||||
Tests for transaction validation are separate.
|
||||
"""
|
||||
from copy import deepcopy
|
||||
|
||||
from base58 import b58decode
|
||||
from pytest import raises
|
||||
|
||||
|
||||
@ -110,10 +112,10 @@ def test_output_deserialization(user_Ed25519, user_pub):
|
||||
|
||||
def test_output_hashlock_serialization():
|
||||
from bigchaindb.common.transaction import Output
|
||||
from cryptoconditions import PreimageSha256Fulfillment
|
||||
from cryptoconditions import PreimageSha256
|
||||
|
||||
secret = b'wow much secret'
|
||||
hashlock = PreimageSha256Fulfillment(preimage=secret).condition_uri
|
||||
hashlock = PreimageSha256(preimage=secret).condition_uri
|
||||
|
||||
expected = {
|
||||
'condition': {
|
||||
@ -129,10 +131,10 @@ def test_output_hashlock_serialization():
|
||||
|
||||
def test_output_hashlock_deserialization():
|
||||
from bigchaindb.common.transaction import Output
|
||||
from cryptoconditions import PreimageSha256Fulfillment
|
||||
from cryptoconditions import PreimageSha256
|
||||
|
||||
secret = b'wow much secret'
|
||||
hashlock = PreimageSha256Fulfillment(preimage=secret).condition_uri
|
||||
hashlock = PreimageSha256(preimage=secret).condition_uri
|
||||
expected = Output(hashlock, amount=1)
|
||||
|
||||
cond = {
|
||||
@ -161,15 +163,15 @@ def test_invalid_output_initialization(cond_uri, user_pub):
|
||||
|
||||
def test_generate_output_split_half_recursive(user_pub, user2_pub, user3_pub):
|
||||
from bigchaindb.common.transaction import Output
|
||||
from cryptoconditions import Ed25519Fulfillment, ThresholdSha256Fulfillment
|
||||
from cryptoconditions import Ed25519Sha256, ThresholdSha256
|
||||
|
||||
expected_simple1 = Ed25519Fulfillment(public_key=user_pub)
|
||||
expected_simple2 = Ed25519Fulfillment(public_key=user2_pub)
|
||||
expected_simple3 = Ed25519Fulfillment(public_key=user3_pub)
|
||||
expected_simple1 = Ed25519Sha256(public_key=b58decode(user_pub))
|
||||
expected_simple2 = Ed25519Sha256(public_key=b58decode(user2_pub))
|
||||
expected_simple3 = Ed25519Sha256(public_key=b58decode(user3_pub))
|
||||
|
||||
expected = ThresholdSha256Fulfillment(threshold=2)
|
||||
expected = ThresholdSha256(threshold=2)
|
||||
expected.add_subfulfillment(expected_simple1)
|
||||
expected_threshold = ThresholdSha256Fulfillment(threshold=2)
|
||||
expected_threshold = ThresholdSha256(threshold=2)
|
||||
expected_threshold.add_subfulfillment(expected_simple2)
|
||||
expected_threshold.add_subfulfillment(expected_simple3)
|
||||
expected.add_subfulfillment(expected_threshold)
|
||||
@ -181,14 +183,14 @@ def test_generate_output_split_half_recursive(user_pub, user2_pub, user3_pub):
|
||||
def test_generate_outputs_split_half_single_owner(user_pub,
|
||||
user2_pub, user3_pub):
|
||||
from bigchaindb.common.transaction import Output
|
||||
from cryptoconditions import Ed25519Fulfillment, ThresholdSha256Fulfillment
|
||||
from cryptoconditions import Ed25519Sha256, ThresholdSha256
|
||||
|
||||
expected_simple1 = Ed25519Fulfillment(public_key=user_pub)
|
||||
expected_simple2 = Ed25519Fulfillment(public_key=user2_pub)
|
||||
expected_simple3 = Ed25519Fulfillment(public_key=user3_pub)
|
||||
expected_simple1 = Ed25519Sha256(public_key=b58decode(user_pub))
|
||||
expected_simple2 = Ed25519Sha256(public_key=b58decode(user2_pub))
|
||||
expected_simple3 = Ed25519Sha256(public_key=b58decode(user3_pub))
|
||||
|
||||
expected = ThresholdSha256Fulfillment(threshold=2)
|
||||
expected_threshold = ThresholdSha256Fulfillment(threshold=2)
|
||||
expected = ThresholdSha256(threshold=2)
|
||||
expected_threshold = ThresholdSha256(threshold=2)
|
||||
expected_threshold.add_subfulfillment(expected_simple2)
|
||||
expected_threshold.add_subfulfillment(expected_simple3)
|
||||
expected.add_subfulfillment(expected_threshold)
|
||||
@ -200,13 +202,13 @@ def test_generate_outputs_split_half_single_owner(user_pub,
|
||||
|
||||
def test_generate_outputs_flat_ownage(user_pub, user2_pub, user3_pub):
|
||||
from bigchaindb.common.transaction import Output
|
||||
from cryptoconditions import Ed25519Fulfillment, ThresholdSha256Fulfillment
|
||||
from cryptoconditions import Ed25519Sha256, ThresholdSha256
|
||||
|
||||
expected_simple1 = Ed25519Fulfillment(public_key=user_pub)
|
||||
expected_simple2 = Ed25519Fulfillment(public_key=user2_pub)
|
||||
expected_simple3 = Ed25519Fulfillment(public_key=user3_pub)
|
||||
expected_simple1 = Ed25519Sha256(public_key=b58decode(user_pub))
|
||||
expected_simple2 = Ed25519Sha256(public_key=b58decode(user2_pub))
|
||||
expected_simple3 = Ed25519Sha256(public_key=b58decode(user3_pub))
|
||||
|
||||
expected = ThresholdSha256Fulfillment(threshold=3)
|
||||
expected = ThresholdSha256(threshold=3)
|
||||
expected.add_subfulfillment(expected_simple1)
|
||||
expected.add_subfulfillment(expected_simple2)
|
||||
expected.add_subfulfillment(expected_simple3)
|
||||
@ -217,9 +219,9 @@ def test_generate_outputs_flat_ownage(user_pub, user2_pub, user3_pub):
|
||||
|
||||
def test_generate_output_single_owner(user_pub):
|
||||
from bigchaindb.common.transaction import Output
|
||||
from cryptoconditions import Ed25519Fulfillment
|
||||
from cryptoconditions import Ed25519Sha256
|
||||
|
||||
expected = Ed25519Fulfillment(public_key=user_pub)
|
||||
expected = Ed25519Sha256(public_key=b58decode(user_pub))
|
||||
cond = Output.generate([user_pub], 1)
|
||||
|
||||
assert cond.fulfillment.to_dict() == expected.to_dict()
|
||||
@ -227,9 +229,9 @@ def test_generate_output_single_owner(user_pub):
|
||||
|
||||
def test_generate_output_single_owner_with_output(user_pub):
|
||||
from bigchaindb.common.transaction import Output
|
||||
from cryptoconditions import Ed25519Fulfillment
|
||||
from cryptoconditions import Ed25519Sha256
|
||||
|
||||
expected = Ed25519Fulfillment(public_key=user_pub)
|
||||
expected = Ed25519Sha256(public_key=b58decode(user_pub))
|
||||
cond = Output.generate([expected], 1)
|
||||
|
||||
assert cond.fulfillment.to_dict() == expected.to_dict()
|
||||
@ -489,15 +491,13 @@ def test_sign_with_invalid_parameters(utx, user_priv):
|
||||
|
||||
def test_validate_tx_simple_create_signature(user_input, user_output, user_priv,
|
||||
asset_definition):
|
||||
from copy import deepcopy
|
||||
from bigchaindb.common.crypto import PrivateKey
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from .utils import validate_transaction_model
|
||||
|
||||
tx = Transaction(Transaction.CREATE, asset_definition, [user_input], [user_output])
|
||||
expected = deepcopy(user_output)
|
||||
message = str(tx).encode()
|
||||
expected.fulfillment.sign(message, PrivateKey(user_priv))
|
||||
expected.fulfillment.sign(message, b58decode(user_priv))
|
||||
tx.sign([user_priv])
|
||||
|
||||
assert tx.inputs[0].to_dict()['fulfillment'] == \
|
||||
@ -527,7 +527,7 @@ def test_sign_threshold_with_invalid_params(utx, user_user2_threshold_input,
|
||||
'somemessage',
|
||||
{user3_pub: user3_priv})
|
||||
with raises(KeypairMismatchException):
|
||||
user_user2_threshold_input.owners_before = ['somewrongvalue']
|
||||
user_user2_threshold_input.owners_before = [58 * 'a']
|
||||
utx._sign_threshold_signature_fulfillment(user_user2_threshold_input,
|
||||
'somemessage',
|
||||
None)
|
||||
@ -551,9 +551,6 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_input,
|
||||
user_priv,
|
||||
user2_priv,
|
||||
asset_definition):
|
||||
from copy import deepcopy
|
||||
|
||||
from bigchaindb.common.crypto import PrivateKey
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from .utils import validate_transaction_model
|
||||
|
||||
@ -562,10 +559,10 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_input,
|
||||
[user_user2_threshold_output])
|
||||
message = str(tx).encode()
|
||||
expected = deepcopy(user_user2_threshold_output)
|
||||
expected.fulfillment.subconditions[0]['body'].sign(message,
|
||||
PrivateKey(user_priv))
|
||||
expected.fulfillment.subconditions[1]['body'].sign(message,
|
||||
PrivateKey(user2_priv))
|
||||
expected.fulfillment.subconditions[0]['body'].sign(
|
||||
message, b58decode(user_priv))
|
||||
expected.fulfillment.subconditions[1]['body'].sign(
|
||||
message, b58decode(user2_priv))
|
||||
tx.sign([user_priv, user2_priv])
|
||||
|
||||
assert tx.inputs[0].to_dict()['fulfillment'] == \
|
||||
@ -577,14 +574,14 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_input,
|
||||
|
||||
def test_validate_tx_threshold_duplicated_pk(user_pub, user_priv,
|
||||
asset_definition):
|
||||
from copy import deepcopy
|
||||
from cryptoconditions import Ed25519Fulfillment, ThresholdSha256Fulfillment
|
||||
from cryptoconditions import Ed25519Sha256, ThresholdSha256
|
||||
from bigchaindb.common.transaction import Input, Output, Transaction
|
||||
from bigchaindb.common.crypto import PrivateKey
|
||||
|
||||
threshold = ThresholdSha256Fulfillment(threshold=2)
|
||||
threshold.add_subfulfillment(Ed25519Fulfillment(public_key=user_pub))
|
||||
threshold.add_subfulfillment(Ed25519Fulfillment(public_key=user_pub))
|
||||
threshold = ThresholdSha256(threshold=2)
|
||||
threshold.add_subfulfillment(
|
||||
Ed25519Sha256(public_key=b58decode(user_pub)))
|
||||
threshold.add_subfulfillment(
|
||||
Ed25519Sha256(public_key=b58decode(user_pub)))
|
||||
|
||||
threshold_input = Input(threshold, [user_pub, user_pub])
|
||||
threshold_output = Output(threshold, [user_pub, user_pub])
|
||||
@ -592,10 +589,10 @@ def test_validate_tx_threshold_duplicated_pk(user_pub, user_priv,
|
||||
tx = Transaction(Transaction.CREATE, asset_definition,
|
||||
[threshold_input], [threshold_output])
|
||||
expected = deepcopy(threshold_input)
|
||||
expected.fulfillment.subconditions[0]['body'].sign(str(tx).encode(),
|
||||
PrivateKey(user_priv))
|
||||
expected.fulfillment.subconditions[1]['body'].sign(str(tx).encode(),
|
||||
PrivateKey(user_priv))
|
||||
expected.fulfillment.subconditions[0]['body'].sign(
|
||||
str(tx).encode(), b58decode(user_priv))
|
||||
expected.fulfillment.subconditions[1]['body'].sign(
|
||||
str(tx).encode(), b58decode(user_priv))
|
||||
|
||||
tx.sign([user_priv, user_priv])
|
||||
|
||||
@ -616,10 +613,9 @@ def test_multiple_input_validation_of_transfer_tx(user_input, user_output,
|
||||
user2_priv, user3_pub,
|
||||
user3_priv,
|
||||
asset_definition):
|
||||
from copy import deepcopy
|
||||
from bigchaindb.common.transaction import (Transaction, TransactionLink,
|
||||
Input, Output)
|
||||
from cryptoconditions import Ed25519Fulfillment
|
||||
from cryptoconditions import Ed25519Sha256
|
||||
from .utils import validate_transaction_model
|
||||
|
||||
tx = Transaction(Transaction.CREATE, asset_definition, [user_input],
|
||||
@ -629,8 +625,10 @@ def test_multiple_input_validation_of_transfer_tx(user_input, user_output,
|
||||
inputs = [Input(cond.fulfillment, cond.public_keys,
|
||||
TransactionLink(tx.id, index))
|
||||
for index, cond in enumerate(tx.outputs)]
|
||||
outputs = [Output(Ed25519Fulfillment(public_key=user3_pub), [user3_pub]),
|
||||
Output(Ed25519Fulfillment(public_key=user3_pub), [user3_pub])]
|
||||
outputs = [Output(Ed25519Sha256(public_key=b58decode(user3_pub)),
|
||||
[user3_pub]),
|
||||
Output(Ed25519Sha256(public_key=b58decode(user3_pub)),
|
||||
[user3_pub])]
|
||||
transfer_tx = Transaction('TRANSFER', {'id': tx.id}, inputs, outputs)
|
||||
transfer_tx = transfer_tx.sign([user_priv])
|
||||
|
||||
@ -640,11 +638,11 @@ def test_multiple_input_validation_of_transfer_tx(user_input, user_output,
|
||||
|
||||
|
||||
def test_validate_inputs_of_transfer_tx_with_invalid_params(
|
||||
transfer_tx, cond_uri, utx, user2_pub, user_priv):
|
||||
transfer_tx, cond_uri, utx, user2_pub, user_priv, ffill_uri):
|
||||
from bigchaindb.common.transaction import Output
|
||||
from cryptoconditions import Ed25519Fulfillment
|
||||
from cryptoconditions import Ed25519Sha256
|
||||
|
||||
invalid_out = Output(Ed25519Fulfillment.from_uri('cf:0:'), ['invalid'])
|
||||
invalid_out = Output(Ed25519Sha256.from_uri(ffill_uri), ['invalid'])
|
||||
assert transfer_tx.inputs_valid([invalid_out]) is False
|
||||
invalid_out = utx.outputs[0]
|
||||
invalid_out.public_key = 'invalid'
|
||||
@ -826,8 +824,6 @@ def test_outputs_to_inputs(tx):
|
||||
|
||||
def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub,
|
||||
user2_output, user_priv):
|
||||
from copy import deepcopy
|
||||
from bigchaindb.common.crypto import PrivateKey
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from bigchaindb.common.utils import serialize
|
||||
from .utils import validate_transaction_model
|
||||
@ -861,8 +857,8 @@ def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub,
|
||||
|
||||
expected_input = deepcopy(inputs[0])
|
||||
expected['id'] = transfer_tx['id']
|
||||
expected_input.fulfillment.sign(serialize(expected).encode(),
|
||||
PrivateKey(user_priv))
|
||||
expected_input.fulfillment.sign(
|
||||
serialize(expected).encode(), b58decode(user_priv))
|
||||
expected_ffill = expected_input.fulfillment.serialize_uri()
|
||||
transfer_ffill = transfer_tx['inputs'][0]['fulfillment']
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
from time import sleep
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from unittest.mock import patch
|
||||
from base58 import b58decode
|
||||
|
||||
pytestmark = pytest.mark.bdb
|
||||
|
||||
@ -577,14 +578,14 @@ class TestBigchainApi(object):
|
||||
|
||||
@pytest.mark.usefixtures('inputs')
|
||||
def test_non_create_input_not_found(self, b, user_pk):
|
||||
from cryptoconditions import Ed25519Fulfillment
|
||||
from cryptoconditions import Ed25519Sha256
|
||||
from bigchaindb.common.exceptions import InputDoesNotExist
|
||||
from bigchaindb.common.transaction import Input, TransactionLink
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb import Bigchain
|
||||
|
||||
# Create an input for a non existing transaction
|
||||
input = Input(Ed25519Fulfillment(public_key=user_pk),
|
||||
input = Input(Ed25519Sha256(public_key=b58decode(user_pk)),
|
||||
[user_pk],
|
||||
TransactionLink('somethingsomething', 0))
|
||||
tx = Transaction.transfer([input], [([user_pk], 1)],
|
||||
|
@ -180,7 +180,7 @@ def test_vote_accumulates_transactions(b):
|
||||
validation = vote_obj.validate_tx(tx.to_dict(), 123, 1)
|
||||
assert validation == (True, 123, 1)
|
||||
|
||||
tx.inputs[0].fulfillment.signature = None
|
||||
tx.inputs[0].fulfillment.signature = 64*b'z'
|
||||
validation = vote_obj.validate_tx(tx.to_dict(), 456, 10)
|
||||
assert validation == (False, 456, 10)
|
||||
|
||||
|
@ -89,7 +89,7 @@ def test_post_create_transaction_with_invalid_signature(mock_logger,
|
||||
|
||||
tx = Transaction.create([user_pub], [([user_pub], 1)])
|
||||
tx = tx.sign([user_priv]).to_dict()
|
||||
tx['inputs'][0]['fulfillment'] = 'cf:0:0'
|
||||
tx['inputs'][0]['fulfillment'] = 64 * '0'
|
||||
|
||||
res = client.post(TX_ENDPOINT, data=json.dumps(tx))
|
||||
expected_status_code = 400
|
||||
|
Loading…
x
Reference in New Issue
Block a user