mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Merge remote-tracking branch 'remotes/origin/feat/128/multiple-input-output' into feat/127/crypto-conditions-ilp-bigchain-integration
Conflicts: bigchaindb/core.py
This commit is contained in:
commit
a7ca11a593
@ -131,32 +131,26 @@ class BaseConsensusRules(AbstractConsensusRules):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
# check if the input exists, is owned by the current_owner
|
# check if the input exists, is owned by the current_owner
|
||||||
if not transaction['transaction']['inputs']:
|
if not transaction['transaction']['fulfillments']:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'Only `CREATE` transactions can have null inputs')
|
'Transaction contains no fulfillments')
|
||||||
|
|
||||||
# check inputs
|
# check inputs
|
||||||
for inp in transaction['transaction']['inputs']:
|
for fulfillment in transaction['transaction']['fulfillments']:
|
||||||
tx_input = bigchain.get_transaction(inp)
|
tx_input = bigchain.get_transaction(fulfillment['input']['txid'])
|
||||||
|
|
||||||
if not tx_input:
|
if not tx_input:
|
||||||
raise exceptions.TransactionDoesNotExist(
|
raise exceptions.TransactionDoesNotExist(
|
||||||
'input `{}` does not exist in the bigchain'.format(
|
'input `{}` does not exist in the bigchain'.format(
|
||||||
transaction['transaction']['input']))
|
fulfillment['input']['txid']))
|
||||||
|
|
||||||
if (tx_input['transaction']['new_owner'] !=
|
|
||||||
transaction['transaction']['current_owner']):
|
|
||||||
raise exceptions.TransactionOwnerError(
|
|
||||||
'current_owner `{}` does not own the input `{}`'.format(
|
|
||||||
transaction['transaction']['current_owner'],
|
|
||||||
transaction['transaction']['input']))
|
|
||||||
|
|
||||||
# check if the input was already spent by a transaction other than
|
# check if the input was already spent by a transaction other than
|
||||||
# this one.
|
# this one.
|
||||||
spent = bigchain.get_spent(tx_input['id'])
|
spent = bigchain.get_spent(fulfillment['input'])
|
||||||
|
print(spent)
|
||||||
if spent and spent['id'] != transaction['id']:
|
if spent and spent['id'] != transaction['id']:
|
||||||
raise exceptions.DoubleSpend(
|
raise exceptions.DoubleSpend(
|
||||||
'input `{}` was already spent'.format(inp))
|
'input `{}` was already spent'.format(fulfillment['input']))
|
||||||
|
|
||||||
# Check hash of the transaction
|
# Check hash of the transaction
|
||||||
# remove the fulfillment messages (signatures)
|
# remove the fulfillment messages (signatures)
|
||||||
|
@ -186,29 +186,31 @@ class Bigchain(object):
|
|||||||
transactions = list(cursor)
|
transactions = list(cursor)
|
||||||
return transactions
|
return transactions
|
||||||
|
|
||||||
def get_spent(self, txid):
|
def get_spent(self, inp):
|
||||||
"""Check if a `txid` was already used as an input.
|
"""Check if a `txid` was already used as an input.
|
||||||
|
|
||||||
A transaction can be used as an input for another transaction. Bigchain needs to make sure that a
|
A transaction can be used as an input for another transaction. Bigchain needs to make sure that a
|
||||||
given `txid` is only used once.
|
given `txid` is only used once.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
txid (str): transaction id.
|
inp (dict): Input of a transaction in the form `{'txid': 'transaction id', 'cid': 'condition id'}`
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The transaction that used the `txid` as an input if it exists else it returns `None`
|
The transaction that used the `txid` as an input if it exists else it returns `None`
|
||||||
"""
|
"""
|
||||||
# checks if an input was already spent
|
# checks if an input was already spent
|
||||||
# checks if the bigchain has any transaction with input `transaction_id`
|
# checks if the bigchain has any transaction with input {'txid': ..., 'cid': ...}
|
||||||
response = r.table('bigchain').concat_map(lambda doc: doc['block']['transactions']) \
|
response = r.table('bigchain').concat_map(lambda doc: doc['block']['transactions'])\
|
||||||
.filter(lambda transaction: transaction['transaction']['inputs'].contains(txid)).run(self.conn)
|
.filter(lambda transaction: transaction['transaction']['fulfillments']
|
||||||
|
.contains(lambda fulfillment: fulfillment['input'] == inp))\
|
||||||
|
.run(self.conn)
|
||||||
|
|
||||||
# a transaction_id should have been spent at most one time
|
# a transaction_id should have been spent at most one time
|
||||||
transactions = list(response)
|
transactions = list(response)
|
||||||
if transactions:
|
if transactions:
|
||||||
if len(transactions) != 1:
|
if len(transactions) != 1:
|
||||||
raise Exception('`{}` was spent more then once. There is a problem with the chain'.format(
|
raise Exception('`{}` was spent more then once. There is a problem with the chain'.format(
|
||||||
txid))
|
inp['txid']))
|
||||||
else:
|
else:
|
||||||
return transactions[0]
|
return transactions[0]
|
||||||
else:
|
else:
|
||||||
|
@ -221,7 +221,7 @@ def create_tx(current_owners, new_owners, inputs, operation, payload=None):
|
|||||||
return transaction
|
return transaction
|
||||||
|
|
||||||
|
|
||||||
#TODO: Change sign_tx to populate the fulfillments
|
# TODO: Change sign_tx to populate the fulfillments
|
||||||
def sign_tx(transaction, private_key):
|
def sign_tx(transaction, private_key):
|
||||||
"""Sign a transaction
|
"""Sign a transaction
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ def sign_tx(transaction, private_key):
|
|||||||
# update the fulfillment message
|
# update the fulfillment message
|
||||||
fulfillment_message.update({
|
fulfillment_message.update({
|
||||||
'input': fulfillment['input'],
|
'input': fulfillment['input'],
|
||||||
'condition': conditions[fulfillment['cid']]
|
'condition': conditions[fulfillment['fid']]
|
||||||
})
|
})
|
||||||
|
|
||||||
# sign the fulfillment message
|
# sign the fulfillment message
|
||||||
@ -322,7 +322,7 @@ def verify_signature(signed_transaction):
|
|||||||
# get previous condition
|
# get previous condition
|
||||||
previous_tx = b.get_transaction(fulfillment['input']['txid'])
|
previous_tx = b.get_transaction(fulfillment['input']['txid'])
|
||||||
conditions = sorted(previous_tx['transaction']['conditions'], key=lambda d: d['cid'])
|
conditions = sorted(previous_tx['transaction']['conditions'], key=lambda d: d['cid'])
|
||||||
fulfillment_message['condition'] = conditions[fulfillment['cid']]
|
fulfillment_message['condition'] = conditions[fulfillment['fid']]
|
||||||
|
|
||||||
# verify the signature (for now lets assume there is only one owner)
|
# verify the signature (for now lets assume there is only one owner)
|
||||||
vk = crypto.VerifyingKey(fulfillment['current_owners'][0])
|
vk = crypto.VerifyingKey(fulfillment['current_owners'][0])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user