mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
change fulfills.idx to fulfills.output
This commit is contained in:
parent
d479a186a4
commit
4e17fe5c3d
@ -95,13 +95,13 @@ def get_asset_by_id(connection, asset_id):
|
||||
|
||||
|
||||
@register_query(RethinkDBConnection)
|
||||
def get_spent(connection, transaction_id, output_id):
|
||||
def get_spent(connection, transaction_id, output):
|
||||
# TODO: use index!
|
||||
return connection.run(
|
||||
r.table('bigchain', read_mode=READ_MODE)
|
||||
.concat_map(lambda doc: doc['block']['transactions'])
|
||||
.filter(lambda transaction: transaction['inputs'].contains(
|
||||
lambda input: input['fulfills'] == {'txid': transaction_id, 'idx': output_id})))
|
||||
lambda input: input['fulfills'] == {'txid': transaction_id, 'output': output})))
|
||||
|
||||
|
||||
@register_query(RethinkDBConnection)
|
||||
|
@ -214,10 +214,10 @@ definitions:
|
||||
Reference to the output that is being spent.
|
||||
additionalProperties: false
|
||||
required:
|
||||
- idx
|
||||
- output
|
||||
- txid
|
||||
properties:
|
||||
idx:
|
||||
output:
|
||||
"$ref": "#/definitions/offset"
|
||||
description: |
|
||||
Index of the output containing the condition being fulfilled
|
||||
|
@ -132,11 +132,11 @@ class TransactionLink(object):
|
||||
|
||||
Attributes:
|
||||
txid (str, optional): A Transaction to link to.
|
||||
idx (int, optional): An output's index in a Transaction with id
|
||||
output (int, optional): An output's index in a Transaction with id
|
||||
`txid`.
|
||||
"""
|
||||
|
||||
def __init__(self, txid=None, idx=None):
|
||||
def __init__(self, txid=None, output=None):
|
||||
"""Create an instance of a :class:`~.TransactionLink`.
|
||||
|
||||
Note:
|
||||
@ -144,18 +144,18 @@ class TransactionLink(object):
|
||||
as an IPLD link can simply point to an object, as well as an
|
||||
objects properties. So instead of having a (de)serializable
|
||||
class, we can have a simple IPLD link of the form:
|
||||
`/<tx_id>/transaction/outputs/<idx>/`.
|
||||
`/<tx_id>/transaction/outputs/<output>/`.
|
||||
|
||||
Args:
|
||||
txid (str, optional): A Transaction to link to.
|
||||
idx (int, optional): An Outputs's index in a Transaction with
|
||||
output (int, optional): An Outputs's index in a Transaction with
|
||||
id `txid`.
|
||||
"""
|
||||
self.txid = txid
|
||||
self.idx = idx
|
||||
self.output = output
|
||||
|
||||
def __bool__(self):
|
||||
return self.txid is not None and self.idx is not None
|
||||
return self.txid is not None and self.output is not None
|
||||
|
||||
def __eq__(self, other):
|
||||
# TODO: If `other !== TransactionLink` return `False`
|
||||
@ -172,7 +172,7 @@ class TransactionLink(object):
|
||||
:class:`~bigchaindb.common.transaction.TransactionLink`
|
||||
"""
|
||||
try:
|
||||
return cls(link['txid'], link['idx'])
|
||||
return cls(link['txid'], link['output'])
|
||||
except TypeError:
|
||||
return cls()
|
||||
|
||||
@ -182,12 +182,12 @@ class TransactionLink(object):
|
||||
Returns:
|
||||
(dict|None): The link as an alternative serialization format.
|
||||
"""
|
||||
if self.txid is None and self.idx is None:
|
||||
if self.txid is None and self.output is None:
|
||||
return None
|
||||
else:
|
||||
return {
|
||||
'txid': self.txid,
|
||||
'idx': self.idx,
|
||||
'output': self.output,
|
||||
}
|
||||
|
||||
def to_uri(self, path=''):
|
||||
|
@ -356,7 +356,7 @@ class Bigchain(object):
|
||||
if cursor:
|
||||
return Asset.from_dict(cursor[0]['asset'])
|
||||
|
||||
def get_spent(self, txid, idx):
|
||||
def get_spent(self, txid, output):
|
||||
"""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
|
||||
@ -364,7 +364,7 @@ class Bigchain(object):
|
||||
|
||||
Args:
|
||||
txid (str): The id of the transaction
|
||||
idx (num): the index of the output in the respective transaction
|
||||
output (num): the index of the output in the respective transaction
|
||||
|
||||
Returns:
|
||||
The transaction (Transaction) that used the `txid` as an input else
|
||||
@ -372,8 +372,8 @@ class Bigchain(object):
|
||||
"""
|
||||
# checks if an input was already spent
|
||||
# checks if the bigchain has any transaction with input {'txid': ...,
|
||||
# 'idx': ...}
|
||||
transactions = list(backend.query.get_spent(self.connection, txid, idx))
|
||||
# 'output': ...}
|
||||
transactions = list(backend.query.get_spent(self.connection, txid, output))
|
||||
|
||||
# a transaction_id should have been spent at most one time
|
||||
if transactions:
|
||||
@ -405,7 +405,7 @@ class Bigchain(object):
|
||||
owner (str): base58 encoded public key.
|
||||
|
||||
Returns:
|
||||
:obj:`list` of TransactionLink: list of ``txid`` s and ``idx`` s
|
||||
:obj:`list` of TransactionLink: list of ``txid`` s and ``output`` s
|
||||
pointing to another transaction's condition
|
||||
"""
|
||||
|
||||
@ -437,7 +437,7 @@ class Bigchain(object):
|
||||
if util.condition_details_has_owner(output['condition']['details'], owner):
|
||||
tx_link = TransactionLink(tx['id'], index)
|
||||
# check if input was already spent
|
||||
if not self.get_spent(tx_link.txid, tx_link.idx):
|
||||
if not self.get_spent(tx_link.txid, tx_link.output):
|
||||
owned.append(tx_link)
|
||||
|
||||
return owned
|
||||
|
@ -56,7 +56,6 @@ class Transaction(Transaction):
|
||||
input_amount = 0
|
||||
for input in self.inputs:
|
||||
input_txid = input.fulfills.txid
|
||||
input_idx = input.fulfills.idx
|
||||
input_tx, status = bigchain.\
|
||||
get_transaction(input_txid, include_status=True)
|
||||
|
||||
@ -69,16 +68,17 @@ class Transaction(Transaction):
|
||||
'input `{}` does not exist in a valid block'.format(
|
||||
input_txid))
|
||||
|
||||
spent = bigchain.get_spent(input_txid, input_idx)
|
||||
spent = bigchain.get_spent(input_txid, input.fulfills.output)
|
||||
if spent and spent.id != self.id:
|
||||
raise DoubleSpend('input `{}` was already spent'
|
||||
.format(input_txid))
|
||||
|
||||
input_conditions.append(input_tx.outputs[input_idx])
|
||||
output = input_tx.outputs[input.fulfills.output]
|
||||
input_conditions.append(output)
|
||||
input_txs.append(input_tx)
|
||||
if input_tx.outputs[input_idx].amount < 1:
|
||||
if output.amount < 1:
|
||||
raise AmountError('`amount` needs to be greater than zero')
|
||||
input_amount += input_tx.outputs[input_idx].amount
|
||||
input_amount += output.amount
|
||||
|
||||
# validate asset id
|
||||
asset_id = Asset.get_asset_id(input_txs)
|
||||
|
@ -387,7 +387,7 @@ def test_transaction_link_serialization():
|
||||
tx_id = 'a transaction id'
|
||||
expected = {
|
||||
'txid': tx_id,
|
||||
'idx': 0,
|
||||
'output': 0,
|
||||
}
|
||||
tx_link = TransactionLink(tx_id, 0)
|
||||
|
||||
@ -410,7 +410,7 @@ def test_transaction_link_deserialization():
|
||||
expected = TransactionLink(tx_id, 0)
|
||||
tx_link = {
|
||||
'txid': tx_id,
|
||||
'idx': 0,
|
||||
'output': 0,
|
||||
}
|
||||
tx_link = TransactionLink.from_dict(tx_link)
|
||||
|
||||
@ -896,7 +896,7 @@ def test_outputs_to_inputs(tx):
|
||||
assert input.owners_before == tx.outputs[0].public_keys
|
||||
assert input.fulfillment == tx.outputs[0].fulfillment
|
||||
assert input.fulfills.txid == tx.id
|
||||
assert input.fulfills.idx == 0
|
||||
assert input.fulfills.output == 0
|
||||
|
||||
|
||||
def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub,
|
||||
@ -921,7 +921,7 @@ def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub,
|
||||
'fulfillment': None,
|
||||
'fulfills': {
|
||||
'txid': tx.id,
|
||||
'idx': 0
|
||||
'output': 0
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -970,7 +970,7 @@ def test_create_transfer_transaction_multiple_io(user_pub, user_priv,
|
||||
'fulfillment': None,
|
||||
'fulfills': {
|
||||
'txid': tx.id,
|
||||
'idx': 0
|
||||
'output': 0
|
||||
}
|
||||
}, {
|
||||
'owners_before': [
|
||||
@ -979,7 +979,7 @@ def test_create_transfer_transaction_multiple_io(user_pub, user_priv,
|
||||
'fulfillment': None,
|
||||
'fulfills': {
|
||||
'txid': tx.id,
|
||||
'idx': 1
|
||||
'output': 1
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -1025,7 +1025,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
# check spents
|
||||
input_txid = owned_inputs_user1.txid
|
||||
input_idx = owned_inputs_user1.idx
|
||||
input_idx = owned_inputs_user1.output
|
||||
spent_inputs_user1 = b.get_spent(input_txid, input_idx)
|
||||
assert spent_inputs_user1 is None
|
||||
|
||||
@ -1061,7 +1061,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
# check spents
|
||||
input_txid = owned_inputs_user1.txid
|
||||
input_idx = owned_inputs_user1.idx
|
||||
input_idx = owned_inputs_user1.output
|
||||
spent_inputs_user1 = b.get_spent(input_txid, input_idx)
|
||||
assert spent_inputs_user1 is None
|
||||
|
||||
@ -1105,7 +1105,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
# check spents
|
||||
for input_tx in owned_inputs_user1:
|
||||
assert b.get_spent(input_tx.txid, input_tx.idx) is None
|
||||
assert b.get_spent(input_tx.txid, input_tx.output) is None
|
||||
|
||||
# transfer the first 2 inputs
|
||||
tx_transfer = Transaction.transfer(tx_create.to_inputs()[:2],
|
||||
@ -1117,7 +1117,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
# check that used inputs are marked as spent
|
||||
for ffill in tx_create.to_inputs()[:2]:
|
||||
spent_tx = b.get_spent(ffill.fulfills.txid, ffill.fulfills.idx)
|
||||
spent_tx = b.get_spent(ffill.fulfills.txid, ffill.fulfills.output)
|
||||
assert spent_tx == tx_transfer_signed
|
||||
|
||||
# check if remaining transaction that was unspent is also perceived
|
||||
@ -1147,7 +1147,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
# check spents
|
||||
for input_tx in owned_inputs_user1:
|
||||
assert b.get_spent(input_tx.txid, input_tx.idx) is None
|
||||
assert b.get_spent(input_tx.txid, input_tx.output) is None
|
||||
|
||||
# create a transaction
|
||||
tx = Transaction.transfer(transactions[0].to_inputs(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user