tx with conditions

This commit is contained in:
diminator 2016-04-07 15:41:06 +02:00
parent ce945e3409
commit b76bd72ea0
No known key found for this signature in database
GPG Key ID: C3D8590E6D0D439A
4 changed files with 54 additions and 37 deletions

View File

@ -3,7 +3,6 @@ import random
import json import json
import rapidjson import rapidjson
import bigchaindb import bigchaindb
from bigchaindb import util from bigchaindb import util
from bigchaindb import config_utils from bigchaindb import config_utils
@ -11,7 +10,6 @@ from bigchaindb import exceptions
from bigchaindb import crypto from bigchaindb import crypto
from bigchaindb.monitor import Monitor from bigchaindb.monitor import Monitor
monitor = Monitor() monitor = Monitor()
@ -228,9 +226,12 @@ class Bigchain(object):
response = r.table('bigchain') \ response = r.table('bigchain') \
.concat_map(lambda doc: doc['block']['transactions']) \ .concat_map(lambda doc: doc['block']['transactions']) \
.filter({'transaction': {'new_owner': owner}})\ .filter(lambda tx: tx['transaction']['conditions']
.contains(lambda c: c['new_owners']
.contains(owner))) \
.pluck('id')['id'] \ .pluck('id')['id'] \
.run(self.conn) .run(self.conn)
owned = [] owned = []
# remove all inputs already spent # remove all inputs already spent

View File

@ -144,6 +144,9 @@ def create_tx(current_owners, new_owners, inputs, operation, payload=None):
}, },
} }
""" """
current_owners = current_owners if isinstance(current_owners, list) else [current_owners]
new_owners = new_owners if isinstance(new_owners, list) else [new_owners]
inputs = inputs if isinstance(inputs, list) else [inputs]
# handle payload # handle payload
data = None data = None
@ -159,17 +162,14 @@ def create_tx(current_owners, new_owners, inputs, operation, payload=None):
# handle inputs # handle inputs
fulfillments = [] fulfillments = []
current_owners = current_owners if isinstance(current_owners, list) else [current_owners]
# transfer # transfer
if inputs: if inputs:
for fid, inp in enumerate(inputs): for fid, inp in enumerate(inputs):
fulfillment = ThresholdSha256Fulfillment(threshold=len(current_owners))
for current_owner in current_owners:
fulfillment.add_subfulfillment(Ed25519Fulfillment(public_key=current_owner))
fulfillments.append({ fulfillments.append({
'current_owners': current_owners, 'current_owners': current_owners,
'input': inp, 'input': inp,
'fulfillment': fulfillment.serialize_json(), 'fulfillment': None,
'fid': fid 'fid': fid
}) })
# create # create
@ -184,9 +184,18 @@ def create_tx(current_owners, new_owners, inputs, operation, payload=None):
# handle outputs # handle outputs
conditions = [] conditions = []
for fulfillment in fulfillments: for fulfillment in fulfillments:
if len(new_owners) > 1:
for new_owner in new_owners:
condition = ThresholdSha256Fulfillment(threshold=len(new_owners))
condition.add_subfulfillment(Ed25519Fulfillment(public_key=new_owner))
elif len(new_owners) == 1:
condition = Ed25519Fulfillment(public_key=new_owners[0])
conditions.append({ conditions.append({
'new_owners': new_owners, 'new_owners': new_owners,
'condition': None, 'condition': {
'details': json.loads(condition.serialize_json()),
'uri': condition.condition.serialize_uri()
},
'cid': fulfillment['fid'] 'cid': fulfillment['fid']
}) })
@ -220,7 +229,7 @@ def sign_tx(transaction, private_key):
Args: Args:
transaction (dict): transaction to sign. transaction (dict): transaction to sign.
private_key (str): base58 encoded private key to create a signature of the transaction. private_key (base58 str): base58 encoded private key to create a signature of the transaction.
Returns: Returns:
dict: transaction with the `fulfillment` fields populated. dict: transaction with the `fulfillment` fields populated.

View File

@ -71,7 +71,7 @@ setup(
'rethinkdb==2.2.0.post4', 'rethinkdb==2.2.0.post4',
'pysha3==0.3', 'pysha3==0.3',
'pytz==2015.7', 'pytz==2015.7',
'cryptoconditions==0.1.4', 'cryptoconditions==0.1.5',
'statsd==3.2.1', 'statsd==3.2.1',
'python-rapidjson==0.0.6', 'python-rapidjson==0.0.6',
'logstats==0.2.1', 'logstats==0.2.1',

View File

@ -23,17 +23,24 @@ def test_remove_unclosed_sockets():
class TestBigchainApi(object): class TestBigchainApi(object):
def test_create_transaction(self, b, user_sk): def test_create_transaction_create(self, b, user_sk):
tx = b.create_transaction(b.me, user_sk, None, 'CREATE') tx = b.create_transaction(b.me, user_sk, None, 'CREATE')
assert sorted(tx) == sorted(['id', 'transaction']) assert sorted(tx) == sorted(['id', 'transaction', 'version'])
assert sorted(tx['transaction']) == sorted(['current_owner', 'new_owner', 'input', 'operation', assert sorted(tx['transaction']) == sorted(['conditions', 'data', 'fulfillments', 'operation', 'timestamp'])
'timestamp', 'data'])
def test_create_transaction_with_unsupported_payload_raises(self, b): def test_create_transaction_with_unsupported_payload_raises(self, b):
with pytest.raises(TypeError): with pytest.raises(TypeError):
b.create_transaction('a', 'b', 'c', 'd', payload=[]) b.create_transaction('a', 'b', 'c', 'd', payload=[])
@pytest.mark.usefixtures('inputs')
def test_create_transaction_transfer(self, b, user_vk, user_sk):
input_tx = b.get_owned_ids(user_vk).pop()
tx = b.create_transaction(b.me, user_sk, input_tx, 'TRANSFER')
assert sorted(tx) == sorted(['id', 'transaction', 'version'])
assert sorted(tx['transaction']) == sorted(['conditions', 'data', 'fulfillments', 'operation', 'timestamp'])
def test_transaction_hash(self, b): def test_transaction_hash(self, b):
payload = {'cats': 'are awesome'} payload = {'cats': 'are awesome'}
tx = b.create_transaction('a', 'b', 'c', 'd', payload) tx = b.create_transaction('a', 'b', 'c', 'd', payload)