1
0
mirror of https://github.com/bigchaindb/bigchaindb.git synced 2024-06-28 08:37:45 +02:00

Decouple metadata from transaction

This commit is contained in:
kansi 2017-11-07 10:50:07 +05:30
parent d9d0585228
commit 94ce03cbec
5 changed files with 30 additions and 14 deletions

View File

@ -395,6 +395,13 @@ class Bigchain(object):
' with the chain'.format(txid)) ' with the chain'.format(txid))
# if its not and invalid transaction # if its not and invalid transaction
if status is not None: if status is not None:
if 'metadata' not in transaction:
metadata = list(self.get_metadata([transaction['id']]))
metadata = metadata[0] if metadata else None
if metadata:
metadata.pop('id', None)
transaction.update({'metadata': metadata})
non_invalid_transactions.append(transaction) non_invalid_transactions.append(transaction)
if non_invalid_transactions: if non_invalid_transactions:

View File

@ -5,7 +5,7 @@ from bigchaindb.common.exceptions import (InvalidHash, InvalidSignature,
DoubleSpend, InputDoesNotExist, DoubleSpend, InputDoesNotExist,
TransactionNotInValidBlock, TransactionNotInValidBlock,
AssetIdMismatch, AmountError, AssetIdMismatch, AmountError,
SybilError, SybilError, ValidationError,
DuplicateTransaction) DuplicateTransaction)
from bigchaindb.common.transaction import Transaction from bigchaindb.common.transaction import Transaction
from bigchaindb.common.utils import (gen_timestamp, serialize, from bigchaindb.common.utils import (gen_timestamp, serialize,
@ -47,9 +47,7 @@ class Transaction(Transaction):
'input `{}` does not exist in a valid block'.format( 'input `{}` does not exist in a valid block'.format(
input_txid)) input_txid))
print(input_txid, self.id)
spent = bigchain.get_spent(input_txid, input_.fulfills.output) spent = bigchain.get_spent(input_txid, input_.fulfills.output)
print(spent)
if spent and spent.id != self.id: if spent and spent.id != self.id:
raise DoubleSpend('input `{}` was already spent' raise DoubleSpend('input `{}` was already spent'
.format(input_txid)) .format(input_txid))
@ -116,9 +114,11 @@ class Transaction(Transaction):
# get metadata of the transaction # get metadata of the transaction
metadata = list(bigchain.get_metadata([tx_dict['id']])) metadata = list(bigchain.get_metadata([tx_dict['id']]))
if metadata: if 'metadata' not in tx_dict:
metadata = metadata[0] metadata = metadata[0] if metadata else None
del metadata['id'] if metadata:
metadata.pop('id', None)
tx_dict.update({'metadata': metadata}) tx_dict.update({'metadata': metadata})
return cls.from_dict(tx_dict) return cls.from_dict(tx_dict)
@ -407,8 +407,8 @@ class Block(object):
if isinstance(metadata, dict): if isinstance(metadata, dict):
metadata.update({'id': transaction['id']}) metadata.update({'id': transaction['id']})
metadatas.append(metadata) metadatas.append(metadata)
else: elif metadata:
transaction.update({'metadata': metadata}) raise ValidationError('Invalid value for metadata')
return (metadatas, block_dict) return (metadatas, block_dict)
@ -444,6 +444,10 @@ class Block(object):
and a list of metadata, reconstruct the original block by putting the and a list of metadata, reconstruct the original block by putting the
metadata of each transaction back into its original transaction. metadata of each transaction back into its original transaction.
NOTE: Till a transaction gets accepted the `metadata` of the transaction
is not moved outside of the transaction. So, if a transaction is found to
have metadata then it should not be overridden.
Args: Args:
block_dict (:obj:`dict`): The block dict as returned from a block_dict (:obj:`dict`): The block dict as returned from a
database call. database call.
@ -457,9 +461,13 @@ class Block(object):
metadatal = {m.pop('id'): m for m in metadatal} metadatal = {m.pop('id'): m for m in metadatal}
# add the metadata to their corresponding transactions # add the metadata to their corresponding transactions
for transaction in block_dict['block']['transactions']: for transaction in block_dict['block']['transactions']:
metadata = metadatal.get(transaction['id']) if 'metadata' not in transaction:
if metadata: metadata = metadatal.get(transaction['id'])
transaction.update({'metadata': metadata}) if metadata:
metadata.pop('id', None)
transaction.update({'metadata': metadata})
else:
transaction.update({'metadata': None})
return block_dict return block_dict
@staticmethod @staticmethod

View File

@ -421,7 +421,8 @@ def test_get_new_blocks_feed(b, create_tx):
ts = str(random.random()) ts = str(random.random())
block = Block(transactions=[create_tx], timestamp=ts) block = Block(transactions=[create_tx], timestamp=ts)
b.write_block(block) b.write_block(block)
return block.decouple_assets()[1] block_dict = block.decouple_assets()[1]
return block.decouple_metadata(block_dict)[1]
create_block() create_block()
b1 = create_block() b1 = create_block()

View File

@ -64,7 +64,8 @@ def test_create_tables():
assert conn.run(r.db(dbname).table_list().contains('backlog')) is True assert conn.run(r.db(dbname).table_list().contains('backlog')) is True
assert conn.run(r.db(dbname).table_list().contains('votes')) is True assert conn.run(r.db(dbname).table_list().contains('votes')) is True
assert conn.run(r.db(dbname).table_list().contains('assets')) is True assert conn.run(r.db(dbname).table_list().contains('assets')) is True
assert len(conn.run(r.db(dbname).table_list())) == 4 assert conn.run(r.db(dbname).table_list().contains('metadata')) is True
assert len(conn.run(r.db(dbname).table_list())) == 5
@pytest.mark.bdb @pytest.mark.bdb

View File

@ -38,7 +38,6 @@ def test_get_owned_ids_works_after_double_spend(b, user_pk, user_sk):
input_valid.id, input_valid.id,
{'1': 1}).sign([user_sk]) {'1': 1}).sign([user_sk])
print(tx_valid)
# write the valid tx and wait for voting/block to catch up # write the valid tx and wait for voting/block to catch up
b.write_transaction(tx_valid) b.write_transaction(tx_valid)
time.sleep(5) time.sleep(5)