mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Remove condition details signature, rename subfulfillments to subconditions (#1589)
* implement output.condition.details marshalling and remove signature field * rename outputs[].condition.details.subfulfillments to subconditions * simpler threshold depth overlow handling * pass public_key as kwarg * change ccv1 condition uri in docs * import base58 at top in test_transaction
This commit is contained in:
parent
b1ad6045b6
commit
5e9b7f4ffe
@ -106,3 +106,7 @@ class SybilError(ValidationError):
|
||||
|
||||
class DuplicateTransaction(ValidationError):
|
||||
"""Raised if a duplicated transaction is found"""
|
||||
|
||||
|
||||
class ThresholdTooDeep(ValidationError):
|
||||
"""Raised if threshold condition is too deep"""
|
||||
|
@ -150,8 +150,7 @@ definitions:
|
||||
- uri
|
||||
properties:
|
||||
details:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
"$ref": "#/definitions/condition_details"
|
||||
uri:
|
||||
type: string
|
||||
pattern: "^ni:///sha-256;([a-zA-Z0-9_-]{0,86})?(.+)$"
|
||||
@ -174,28 +173,14 @@ definitions:
|
||||
description: |
|
||||
List of public keys of the previous owners of the asset.
|
||||
fulfillment:
|
||||
description: |
|
||||
Fulfillment of an `Output.condition`_, or, put a different way, a payload
|
||||
that satisfies the condition of a previous output to prove that the
|
||||
creator(s) of this transaction have control over the listed asset.
|
||||
anyOf:
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
bitmask:
|
||||
type: integer
|
||||
public_key:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
signature:
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: 'null'
|
||||
type_id:
|
||||
type: integer
|
||||
description: |
|
||||
Fulfillment of an `Output.condition`_, or, put a different way, a payload
|
||||
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: "^[a-zA-Z0-9_-]*$"
|
||||
- "$ref": "#/definitions/condition_details"
|
||||
fulfills:
|
||||
anyOf:
|
||||
- type: 'object'
|
||||
@ -224,3 +209,37 @@ definitions:
|
||||
additionalProperties: true
|
||||
minProperties: 1
|
||||
- type: 'null'
|
||||
condition_details:
|
||||
description: |
|
||||
Details needed to reconstruct the condition associated with an output.
|
||||
Currently, BigchainDB only supports ed25519 and threshold condition types.
|
||||
anyOf:
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- type
|
||||
- public_key
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
pattern: "^ed25519-sha-256$"
|
||||
public_key:
|
||||
"$ref": "#/definitions/base58"
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- type
|
||||
- threshold
|
||||
- subconditions
|
||||
properties:
|
||||
type:
|
||||
type: "string"
|
||||
pattern: "^threshold-sha-256$"
|
||||
threshold:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
subconditions:
|
||||
type: array
|
||||
items:
|
||||
"$ref": "#/definitions/condition_details"
|
||||
|
@ -4,12 +4,13 @@ from functools import reduce
|
||||
import base58
|
||||
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256
|
||||
from cryptoconditions.exceptions import (
|
||||
ParsingError, ASN1DecodeError, ASN1EncodeError)
|
||||
ParsingError, ASN1DecodeError, ASN1EncodeError, UnsupportedTypeError)
|
||||
|
||||
from bigchaindb.common.crypto import PrivateKey, hash_data
|
||||
from bigchaindb.common.exceptions import (KeypairMismatchException,
|
||||
InvalidHash, InvalidSignature,
|
||||
AmountError, AssetIdMismatch)
|
||||
AmountError, AssetIdMismatch,
|
||||
ThresholdTooDeep)
|
||||
from bigchaindb.common.utils import serialize
|
||||
|
||||
|
||||
@ -66,15 +67,7 @@ class Input(object):
|
||||
try:
|
||||
fulfillment = self.fulfillment.serialize_uri()
|
||||
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
|
||||
# account for its dictionary form but just for its signed uri
|
||||
# form.
|
||||
# Hence, when a non-signed fulfillment is to be cast to a
|
||||
# dict, we just call its internal `to_dict` method here and
|
||||
# its `from_dict` method in `Fulfillment.from_dict`.
|
||||
fulfillment = self.fulfillment.to_dict()
|
||||
fulfillment = _fulfillment_to_details(self.fulfillment)
|
||||
|
||||
try:
|
||||
# NOTE: `self.fulfills` can be `None` and that's fine
|
||||
@ -125,11 +118,63 @@ class Input(object):
|
||||
except TypeError:
|
||||
# NOTE: See comment about this special case in
|
||||
# `Input.to_dict`
|
||||
fulfillment = Fulfillment.from_dict(data['fulfillment'])
|
||||
fulfillment = _fulfillment_from_details(data['fulfillment'])
|
||||
fulfills = TransactionLink.from_dict(data['fulfills'])
|
||||
return cls(fulfillment, data['owners_before'], fulfills)
|
||||
|
||||
|
||||
def _fulfillment_to_details(fulfillment):
|
||||
"""
|
||||
Encode a fulfillment as a details dictionary
|
||||
|
||||
Args:
|
||||
fulfillment: Crypto-conditions Fulfillment object
|
||||
"""
|
||||
|
||||
if fulfillment.type_name == 'ed25519-sha-256':
|
||||
return {
|
||||
'type': 'ed25519-sha-256',
|
||||
'public_key': base58.b58encode(fulfillment.public_key),
|
||||
}
|
||||
|
||||
if fulfillment.type_name == 'threshold-sha-256':
|
||||
subconditions = [
|
||||
_fulfillment_to_details(cond['body'])
|
||||
for cond in fulfillment.subconditions
|
||||
]
|
||||
return {
|
||||
'type': 'threshold-sha-256',
|
||||
'threshold': fulfillment.threshold,
|
||||
'subconditions': subconditions,
|
||||
}
|
||||
|
||||
raise UnsupportedTypeError(fulfillment.type_name)
|
||||
|
||||
|
||||
def _fulfillment_from_details(data):
|
||||
"""
|
||||
Load a fulfillment for a signing spec dictionary
|
||||
|
||||
Args:
|
||||
data: tx.output[].condition.details dictionary
|
||||
"""
|
||||
if data['type'] == 'ed25519-sha-256':
|
||||
public_key = base58.b58decode(data['public_key'])
|
||||
return Ed25519Sha256(public_key=public_key)
|
||||
|
||||
if data['type'] == 'threshold-sha-256':
|
||||
try:
|
||||
threshold = ThresholdSha256(data['threshold'])
|
||||
for cond in data['subconditions']:
|
||||
cond = _fulfillment_from_details(cond)
|
||||
threshold.add_subfulfillment(cond)
|
||||
return threshold
|
||||
except RecursionError:
|
||||
raise ThresholdTooDeep()
|
||||
|
||||
raise UnsupportedTypeError(data.get('type'))
|
||||
|
||||
|
||||
class TransactionLink(object):
|
||||
"""An object for unidirectional linking to a Transaction's Output.
|
||||
|
||||
@ -262,7 +307,7 @@ class Output(object):
|
||||
# and fulfillment!
|
||||
condition = {}
|
||||
try:
|
||||
condition['details'] = self.fulfillment.to_dict()
|
||||
condition['details'] = _fulfillment_to_details(self.fulfillment)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
@ -389,7 +434,7 @@ class Output(object):
|
||||
:class:`~bigchaindb.common.transaction.Output`
|
||||
"""
|
||||
try:
|
||||
fulfillment = Fulfillment.from_dict(data['condition']['details'])
|
||||
fulfillment = _fulfillment_from_details(data['condition']['details'])
|
||||
except KeyError:
|
||||
# NOTE: Hashlock condition case
|
||||
fulfillment = data['condition']['uri']
|
||||
|
@ -96,8 +96,8 @@ def condition_details_has_owner(condition_details, owner):
|
||||
bool: True if the public key is found in the condition details, False otherwise
|
||||
|
||||
"""
|
||||
if 'subfulfillments' in condition_details:
|
||||
result = condition_details_has_owner(condition_details['subfulfillments'], owner)
|
||||
if 'subconditions' in condition_details:
|
||||
result = condition_details_has_owner(condition_details['subconditions'], owner)
|
||||
if result:
|
||||
return True
|
||||
|
||||
|
@ -81,30 +81,20 @@ to spend the asset. For example:
|
||||
{
|
||||
"condition": {
|
||||
"details": {
|
||||
"bitmask": 41,
|
||||
"subfulfillments": [
|
||||
"type": "threshold-sha-256",
|
||||
"threshold": 2,
|
||||
"subconditions": [
|
||||
{
|
||||
"bitmask": 32,
|
||||
"public_key": "<new owner 1 public key>",
|
||||
"signature": null,
|
||||
"type": "fulfillment",
|
||||
"type_id": 4,
|
||||
"weight": 1
|
||||
"type": "ed25519-sha-256",
|
||||
},
|
||||
{
|
||||
"bitmask": 32,
|
||||
"public_key": "<new owner 2 public key>",
|
||||
"signature": null,
|
||||
"type": "fulfillment",
|
||||
"type_id": 4,
|
||||
"weight": 1
|
||||
"type": "ed25519-sha-256",
|
||||
}
|
||||
],
|
||||
"threshold": 2,
|
||||
"type": "fulfillment",
|
||||
"type_id": 2
|
||||
},
|
||||
"uri": "cc:2:29:ytNK3X6-bZsbF-nCGDTuopUIMi1HCyCkyPewm6oLI3o:206"},
|
||||
"uri": "ni:///sha-256;PNYwdxaRaNw60N6LDFzOWO97b8tJeragczakL8PrAPc?fpt=ed25519-sha-256&cost=131072"},
|
||||
"public_keys": [
|
||||
"<owner 1 public key>",
|
||||
"<owner 2 public key>"
|
||||
@ -112,11 +102,10 @@ to spend the asset. For example:
|
||||
}
|
||||
|
||||
|
||||
- ``subfulfillments``: a list of fulfillments
|
||||
- ``weight``: integer weight for each subfulfillment's contribution to the threshold
|
||||
- ``threshold``: threshold to reach for the subfulfillments to reach a valid fulfillment
|
||||
- ``subconditions``: a list of condition specs
|
||||
- ``threshold``: threshold to reach for the subconditions to reach a valid fulfillment
|
||||
|
||||
The ``weight``s and ``threshold`` could be adjusted. For example, if the ``threshold`` was changed to 1 above, then only one of the new owners would have to provide a signature to spend the asset.
|
||||
The ``threshold`` can be adjusted. For example, if the ``threshold`` was changed to 1 above, then only one of the new owners would have to provide a signature to spend the asset. If it is desired to give a different weight to a subcondition, it should be specified multiple times.
|
||||
|
||||
Inputs
|
||||
------
|
||||
|
@ -52,8 +52,8 @@ def test_single_in_single_own_single_out_multiple_own_create(b, user_pk):
|
||||
assert tx_signed.outputs[0].amount == 100
|
||||
|
||||
output = tx_signed.outputs[0].to_dict()
|
||||
assert 'subfulfillments' in output['condition']['details']
|
||||
assert len(output['condition']['details']['subfulfillments']) == 2
|
||||
assert 'subconditions' in output['condition']['details']
|
||||
assert len(output['condition']['details']['subconditions']) == 2
|
||||
|
||||
assert len(tx_signed.inputs) == 1
|
||||
|
||||
@ -76,8 +76,8 @@ def test_single_in_single_own_multiple_out_mix_own_create(b, user_pk):
|
||||
assert tx_signed.outputs[1].amount == 50
|
||||
|
||||
output_cid1 = tx_signed.outputs[1].to_dict()
|
||||
assert 'subfulfillments' in output_cid1['condition']['details']
|
||||
assert len(output_cid1['condition']['details']['subfulfillments']) == 2
|
||||
assert 'subconditions' in output_cid1['condition']['details']
|
||||
assert len(output_cid1['condition']['details']['subconditions']) == 2
|
||||
|
||||
assert len(tx_signed.inputs) == 1
|
||||
|
||||
@ -89,6 +89,7 @@ def test_single_in_single_own_multiple_out_mix_own_create(b, user_pk):
|
||||
def test_single_in_multiple_own_single_out_single_own_create(b, user_pk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import _fulfillment_to_details
|
||||
|
||||
tx = Transaction.create([b.me, user_pk], [([user_pk], 100)])
|
||||
tx_signed = tx.sign([b.me_private, user_sk])
|
||||
@ -97,9 +98,9 @@ def test_single_in_multiple_own_single_out_single_own_create(b, user_pk,
|
||||
assert tx_signed.outputs[0].amount == 100
|
||||
assert len(tx_signed.inputs) == 1
|
||||
|
||||
ffill = tx_signed.inputs[0].fulfillment.to_dict()
|
||||
assert 'subfulfillments' in ffill
|
||||
assert len(ffill['subfulfillments']) == 2
|
||||
ffill = _fulfillment_to_details(tx_signed.inputs[0].fulfillment)
|
||||
assert 'subconditions' in ffill
|
||||
assert len(ffill['subconditions']) == 2
|
||||
|
||||
|
||||
# TRANSFER divisible asset
|
||||
@ -207,8 +208,8 @@ def test_single_in_single_own_single_out_multiple_own_transfer(b, user_pk,
|
||||
assert tx_transfer_signed.outputs[0].amount == 100
|
||||
|
||||
condition = tx_transfer_signed.outputs[0].to_dict()
|
||||
assert 'subfulfillments' in condition['condition']['details']
|
||||
assert len(condition['condition']['details']['subfulfillments']) == 2
|
||||
assert 'subconditions' in condition['condition']['details']
|
||||
assert len(condition['condition']['details']['subconditions']) == 2
|
||||
|
||||
assert len(tx_transfer_signed.inputs) == 1
|
||||
|
||||
@ -248,8 +249,8 @@ def test_single_in_single_own_multiple_out_mix_own_transfer(b, user_pk,
|
||||
assert tx_transfer_signed.outputs[1].amount == 50
|
||||
|
||||
output_cid1 = tx_transfer_signed.outputs[1].to_dict()
|
||||
assert 'subfulfillments' in output_cid1['condition']['details']
|
||||
assert len(output_cid1['condition']['details']['subfulfillments']) == 2
|
||||
assert 'subconditions' in output_cid1['condition']['details']
|
||||
assert len(output_cid1['condition']['details']['subconditions']) == 2
|
||||
|
||||
assert len(tx_transfer_signed.inputs) == 1
|
||||
|
||||
@ -264,6 +265,7 @@ def test_single_in_single_own_multiple_out_mix_own_transfer(b, user_pk,
|
||||
def test_single_in_multiple_own_single_out_single_own_transfer(b, user_pk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import _fulfillment_to_details
|
||||
|
||||
# CREATE divisible asset
|
||||
tx_create = Transaction.create([b.me], [([b.me, user_pk], 100)])
|
||||
@ -286,9 +288,9 @@ def test_single_in_multiple_own_single_out_single_own_transfer(b, user_pk,
|
||||
assert tx_transfer_signed.outputs[0].amount == 100
|
||||
assert len(tx_transfer_signed.inputs) == 1
|
||||
|
||||
ffill = tx_transfer_signed.inputs[0].fulfillment.to_dict()
|
||||
assert 'subfulfillments' in ffill
|
||||
assert len(ffill['subfulfillments']) == 2
|
||||
ffill = _fulfillment_to_details(tx_transfer_signed.inputs[0].fulfillment)
|
||||
assert 'subconditions' in ffill
|
||||
assert len(ffill['subconditions']) == 2
|
||||
|
||||
|
||||
# TRANSFER divisible asset
|
||||
@ -334,6 +336,7 @@ def test_multiple_in_single_own_single_out_single_own_transfer(b, user_pk,
|
||||
def test_multiple_in_multiple_own_single_out_single_own_transfer(b, user_pk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import _fulfillment_to_details
|
||||
|
||||
# CREATE divisible asset
|
||||
tx_create = Transaction.create([b.me], [([user_pk, b.me], 50), ([user_pk, b.me], 50)])
|
||||
@ -356,12 +359,12 @@ def test_multiple_in_multiple_own_single_out_single_own_transfer(b, user_pk,
|
||||
assert tx_transfer_signed.outputs[0].amount == 100
|
||||
assert len(tx_transfer_signed.inputs) == 2
|
||||
|
||||
ffill_fid0 = tx_transfer_signed.inputs[0].fulfillment.to_dict()
|
||||
ffill_fid1 = tx_transfer_signed.inputs[1].fulfillment.to_dict()
|
||||
assert 'subfulfillments' in ffill_fid0
|
||||
assert 'subfulfillments' in ffill_fid1
|
||||
assert len(ffill_fid0['subfulfillments']) == 2
|
||||
assert len(ffill_fid1['subfulfillments']) == 2
|
||||
ffill_fid0 = _fulfillment_to_details(tx_transfer_signed.inputs[0].fulfillment)
|
||||
ffill_fid1 = _fulfillment_to_details(tx_transfer_signed.inputs[1].fulfillment)
|
||||
assert 'subconditions' in ffill_fid0
|
||||
assert 'subconditions' in ffill_fid1
|
||||
assert len(ffill_fid0['subconditions']) == 2
|
||||
assert len(ffill_fid1['subconditions']) == 2
|
||||
|
||||
|
||||
# TRANSFER divisible asset
|
||||
@ -375,6 +378,7 @@ def test_multiple_in_multiple_own_single_out_single_own_transfer(b, user_pk,
|
||||
def test_muiltiple_in_mix_own_multiple_out_single_own_transfer(b, user_pk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import _fulfillment_to_details
|
||||
|
||||
# CREATE divisible asset
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 50), ([user_pk, b.me], 50)])
|
||||
@ -397,11 +401,11 @@ def test_muiltiple_in_mix_own_multiple_out_single_own_transfer(b, user_pk,
|
||||
assert tx_transfer_signed.outputs[0].amount == 100
|
||||
assert len(tx_transfer_signed.inputs) == 2
|
||||
|
||||
ffill_fid0 = tx_transfer_signed.inputs[0].fulfillment.to_dict()
|
||||
ffill_fid1 = tx_transfer_signed.inputs[1].fulfillment.to_dict()
|
||||
assert 'subfulfillments' not in ffill_fid0
|
||||
assert 'subfulfillments' in ffill_fid1
|
||||
assert len(ffill_fid1['subfulfillments']) == 2
|
||||
ffill_fid0 = _fulfillment_to_details(tx_transfer_signed.inputs[0].fulfillment)
|
||||
ffill_fid1 = _fulfillment_to_details(tx_transfer_signed.inputs[1].fulfillment)
|
||||
assert 'subconditions' not in ffill_fid0
|
||||
assert 'subconditions' in ffill_fid1
|
||||
assert len(ffill_fid1['subconditions']) == 2
|
||||
|
||||
|
||||
# TRANSFER divisible asset
|
||||
@ -416,6 +420,7 @@ def test_muiltiple_in_mix_own_multiple_out_single_own_transfer(b, user_pk,
|
||||
def test_muiltiple_in_mix_own_multiple_out_mix_own_transfer(b, user_pk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import _fulfillment_to_details
|
||||
|
||||
# CREATE divisible asset
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 50), ([user_pk, b.me], 50)])
|
||||
@ -442,15 +447,15 @@ def test_muiltiple_in_mix_own_multiple_out_mix_own_transfer(b, user_pk,
|
||||
|
||||
cond_cid0 = tx_transfer_signed.outputs[0].to_dict()
|
||||
cond_cid1 = tx_transfer_signed.outputs[1].to_dict()
|
||||
assert 'subfulfillments' not in cond_cid0['condition']['details']
|
||||
assert 'subfulfillments' in cond_cid1['condition']['details']
|
||||
assert len(cond_cid1['condition']['details']['subfulfillments']) == 2
|
||||
assert 'subconditions' not in cond_cid0['condition']['details']
|
||||
assert 'subconditions' in cond_cid1['condition']['details']
|
||||
assert len(cond_cid1['condition']['details']['subconditions']) == 2
|
||||
|
||||
ffill_fid0 = tx_transfer_signed.inputs[0].fulfillment.to_dict()
|
||||
ffill_fid1 = tx_transfer_signed.inputs[1].fulfillment.to_dict()
|
||||
assert 'subfulfillments' not in ffill_fid0
|
||||
assert 'subfulfillments' in ffill_fid1
|
||||
assert len(ffill_fid1['subfulfillments']) == 2
|
||||
ffill_fid0 = _fulfillment_to_details(tx_transfer_signed.inputs[0].fulfillment)
|
||||
ffill_fid1 = _fulfillment_to_details(tx_transfer_signed.inputs[1].fulfillment)
|
||||
assert 'subconditions' not in ffill_fid0
|
||||
assert 'subconditions' in ffill_fid1
|
||||
assert len(ffill_fid1['subconditions']) == 2
|
||||
|
||||
|
||||
# TRANSFER divisible asset
|
||||
|
@ -4,7 +4,7 @@ Tests for transaction validation are separate.
|
||||
"""
|
||||
from copy import deepcopy
|
||||
|
||||
from base58 import b58decode
|
||||
from base58 import b58encode, b58decode
|
||||
from pytest import raises
|
||||
|
||||
|
||||
@ -82,7 +82,10 @@ def test_output_serialization(user_Ed25519, user_pub):
|
||||
expected = {
|
||||
'condition': {
|
||||
'uri': user_Ed25519.condition_uri,
|
||||
'details': user_Ed25519.to_dict(),
|
||||
'details': {
|
||||
'type': 'ed25519-sha-256',
|
||||
'public_key': b58encode(user_Ed25519.public_key),
|
||||
},
|
||||
},
|
||||
'public_keys': [user_pub],
|
||||
'amount': '1',
|
||||
@ -100,7 +103,10 @@ def test_output_deserialization(user_Ed25519, user_pub):
|
||||
cond = {
|
||||
'condition': {
|
||||
'uri': user_Ed25519.condition_uri,
|
||||
'details': user_Ed25519.to_dict()
|
||||
'details': {
|
||||
'type': 'ed25519-sha-256',
|
||||
'public_key': b58encode(user_Ed25519.public_key),
|
||||
},
|
||||
},
|
||||
'public_keys': [user_pub],
|
||||
'amount': '1',
|
||||
|
@ -5,9 +5,11 @@ structural / schematic issues are caught when reading a transaction
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from bigchaindb.common.exceptions import (AmountError, InvalidHash,
|
||||
SchemaValidationError)
|
||||
SchemaValidationError,
|
||||
ThresholdTooDeep)
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
|
||||
@ -161,6 +163,37 @@ def test_high_amounts(create_tx):
|
||||
validate(create_tx)
|
||||
|
||||
|
||||
################################################################################
|
||||
# Conditions
|
||||
|
||||
def test_handle_threshold_overflow():
|
||||
from bigchaindb.common import transaction
|
||||
|
||||
cond = {
|
||||
'type': 'ed25519-sha-256',
|
||||
'public_key': 'a' * 43,
|
||||
}
|
||||
for i in range(1000):
|
||||
cond = {
|
||||
'type': 'threshold-sha-256',
|
||||
'threshold': 1,
|
||||
'subconditions': [cond],
|
||||
}
|
||||
with pytest.raises(ThresholdTooDeep):
|
||||
transaction._fulfillment_from_details(cond)
|
||||
|
||||
|
||||
def test_unsupported_condition_type():
|
||||
from bigchaindb.common import transaction
|
||||
from cryptoconditions.exceptions import UnsupportedTypeError
|
||||
|
||||
with pytest.raises(UnsupportedTypeError):
|
||||
transaction._fulfillment_from_details({'type': 'a'})
|
||||
|
||||
with pytest.raises(UnsupportedTypeError):
|
||||
transaction._fulfillment_to_details(MagicMock(type_name='a'))
|
||||
|
||||
|
||||
################################################################################
|
||||
# Version
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user