mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Updated validate_transaction to work with crypto conditions.
Updated get_spent to work with multiple inputs
This commit is contained in:
@@ -131,32 +131,26 @@ class BaseConsensusRules(AbstractConsensusRules):
|
||||
|
||||
else:
|
||||
# check if the input exists, is owned by the current_owner
|
||||
if not transaction['transaction']['inputs']:
|
||||
if not transaction['transaction']['fulfillments']:
|
||||
raise ValueError(
|
||||
'Only `CREATE` transactions can have null inputs')
|
||||
'Transaction contains no fulfillments')
|
||||
|
||||
# check inputs
|
||||
for inp in transaction['transaction']['inputs']:
|
||||
tx_input = bigchain.get_transaction(inp)
|
||||
for fulfillment in transaction['transaction']['fulfillments']:
|
||||
tx_input = bigchain.get_transaction(fulfillment['input']['txid'])
|
||||
|
||||
if not tx_input:
|
||||
raise exceptions.TransactionDoesNotExist(
|
||||
'input `{}` does not exist in the bigchain'.format(
|
||||
transaction['transaction']['input']))
|
||||
|
||||
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']))
|
||||
fulfillment['input']['txid']))
|
||||
|
||||
# check if the input was already spent by a transaction other than
|
||||
# this one.
|
||||
spent = bigchain.get_spent(tx_input['id'])
|
||||
spent = bigchain.get_spent(fulfillment['input'])
|
||||
print(spent)
|
||||
if spent and spent['id'] != transaction['id']:
|
||||
raise exceptions.DoubleSpend(
|
||||
'input `{}` was already spent'.format(inp))
|
||||
'input `{}` was already spent'.format(fulfillment['input']))
|
||||
|
||||
# Check hash of the transaction
|
||||
# remove the fulfillment messages (signatures)
|
||||
|
||||
@@ -188,29 +188,31 @@ class Bigchain(object):
|
||||
transactions = list(cursor)
|
||||
return transactions
|
||||
|
||||
def get_spent(self, txid):
|
||||
def get_spent(self, inp):
|
||||
"""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
|
||||
given `txid` is only used once.
|
||||
|
||||
Args:
|
||||
txid (str): transaction id.
|
||||
inp (dict): Input of a transaction in the form `{'txid': 'transaction id', 'cid': 'condition id'}`
|
||||
|
||||
Returns:
|
||||
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 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'])\
|
||||
.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
|
||||
transactions = list(response)
|
||||
if transactions:
|
||||
if len(transactions) != 1:
|
||||
raise Exception('`{}` was spent more then once. There is a problem with the chain'.format(
|
||||
txid))
|
||||
inp['txid']))
|
||||
else:
|
||||
return transactions[0]
|
||||
else:
|
||||
|
||||
@@ -206,7 +206,7 @@ def create_tx(current_owners, new_owners, inputs, operation, payload=None):
|
||||
return transaction
|
||||
|
||||
|
||||
#TODO: Change sign_tx to populate the fulfillments
|
||||
# TODO: Change sign_tx to populate the fulfillments
|
||||
def sign_tx(transaction, private_key):
|
||||
"""Sign a transaction
|
||||
|
||||
|
||||
Reference in New Issue
Block a user