mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
get_transaction to ignore invalid blocks
This commit is contained in:
parent
b69a897b26
commit
3121c9498a
@ -130,7 +130,6 @@ class Bigchain(object):
|
|||||||
response = r.table('backlog').insert(signed_transaction, durability=durability).run(self.conn)
|
response = r.table('backlog').insert(signed_transaction, durability=durability).run(self.conn)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
# TODO: the same `txid` can be in two different blocks
|
|
||||||
def get_transaction(self, txid):
|
def get_transaction(self, txid):
|
||||||
"""Retrieve a transaction with `txid` from bigchain.
|
"""Retrieve a transaction with `txid` from bigchain.
|
||||||
|
|
||||||
@ -145,16 +144,41 @@ class Bigchain(object):
|
|||||||
If no transaction with that `txid` was found it returns `None`
|
If no transaction with that `txid` was found it returns `None`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
response = r.table('bigchain').concat_map(lambda doc: doc['block']['transactions'])\
|
# First, get information on all blocks which contain this transaction
|
||||||
.filter(lambda transaction: transaction['id'] == txid).run(self.conn)
|
response = r.table('bigchain').get_all(txid, index='transaction_id')\
|
||||||
|
.pluck('votes', 'id', {'block': ['voters']}).run(self.conn)
|
||||||
|
|
||||||
|
blocks = list(response)
|
||||||
|
|
||||||
|
if blocks:
|
||||||
|
# Determine the election status of each block
|
||||||
|
validity = {block['id']: self.block_election_status(block) for block in blocks}
|
||||||
|
|
||||||
|
# Disregard invalid blocks, and return if there are no valid or undecided blocks
|
||||||
|
validity = {_id: status for _id, status in validity.items() if status != 'invalid'}
|
||||||
|
if not validity:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# If there are multiple valid blocks with this transaction, something has gone wrong
|
||||||
|
if list(validity.values()).count('valid') > 1:
|
||||||
|
raise Exception('Transaction {tx} is present in multiple valid blocks: {block_ids}'
|
||||||
|
.format(tx=txid,
|
||||||
|
block_ids=str([block for block in validity if validity[block] == 'valid'])))
|
||||||
|
|
||||||
|
# If the transaction is in a valid or any undecided block, return it. Does not check
|
||||||
|
# if transactions in undecided blocks are consistent, but selects the valid block before
|
||||||
|
# undecided ones
|
||||||
|
for _id in validity:
|
||||||
|
target_block_id = _id
|
||||||
|
if validity[_id] == 'valid':
|
||||||
|
break
|
||||||
|
|
||||||
|
# Query the transaction in the target block and return
|
||||||
|
response = r.table('bigchain').filter(lambda block: block['id'] == target_block_id).nth(0)\
|
||||||
|
.get_field('block').get_field('transactions').filter(lambda tx: tx['id'] == txid).run(self.conn)
|
||||||
|
|
||||||
|
return response[0]
|
||||||
|
|
||||||
# transaction ids should be unique
|
|
||||||
transactions = list(response)
|
|
||||||
if transactions:
|
|
||||||
if len(transactions) != 1:
|
|
||||||
raise Exception('Transaction ids should be unique. There is a problem with the chain')
|
|
||||||
else:
|
|
||||||
return transactions[0]
|
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user