def from_dict(cls, block_body): block = block_body['block'] block_serialized = serialize(block) block_id = hash_data(block_serialized) verifying_key = VerifyingKey(block['node_pubkey']) try: signature = block_body['signature'] except KeyError: signature = None if block_id != block_body['id']: raise InvalidHash() if signature is not None: # NOTE: CC throws a `ValueError` on some wrong signatures # https://github.com/bigchaindb/cryptoconditions/issues/27 try: signature_valid = verifying_key.verify(block_serialized, signature) except ValueError: signature_valid = False if signature_valid is False: raise InvalidSignature('Invalid block signature') transactions = [Transaction.from_dict(tx) for tx in block['transactions']] return cls(transactions, block['node_pubkey'], block['timestamp'], block['voters'], signature)
def test_transaction_deserialization(user_ffill, user_cond, data, data_id): from bigchaindb_common.transaction import Transaction, Asset timestamp = '66666666666' expected_asset = Asset(data, data_id) expected = Transaction(Transaction.CREATE, expected_asset, [user_ffill], [user_cond], None, timestamp, Transaction.VERSION) tx = { 'version': Transaction.VERSION, 'transaction': { # NOTE: This test assumes that Fulfillments and Conditions can # successfully be serialized 'fulfillments': [user_ffill.to_dict()], 'conditions': [user_cond.to_dict()], 'operation': Transaction.CREATE, 'timestamp': timestamp, 'metadata': None, 'asset': { 'id': data_id, 'divisible': False, 'updatable': False, 'refillable': False, 'data': data, } } } tx_no_signatures = Transaction._remove_signatures(tx) tx['id'] = Transaction._to_hash(Transaction._to_str(tx_no_signatures)) tx = Transaction.from_dict(tx) assert tx == expected
def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub, user2_cond, user_priv, data_id): from copy import deepcopy from bigchaindb_common.crypto import SigningKey from bigchaindb_common.transaction import Transaction, Asset from bigchaindb_common.util import serialize expected = { 'transaction': { 'conditions': [user2_cond.to_dict(0)], 'metadata': None, 'asset': { 'id': data_id, }, 'fulfillments': [ { 'owners_before': [ user_pub ], 'fid': 0, 'fulfillment': None, 'input': { 'txid': tx.id, 'cid': 0 } } ], 'operation': 'TRANSFER', }, 'version': 1 } inputs = tx.to_inputs([0]) asset = Asset(None, data_id) transfer_tx = Transaction.transfer(inputs, [user2_pub], asset=asset) transfer_tx = transfer_tx.sign([user_priv]) transfer_tx = transfer_tx.to_dict() transfer_tx_body = transfer_tx['transaction'] expected_input = deepcopy(inputs[0]) expected['id'] = transfer_tx['id'] expected['transaction']['timestamp'] = transfer_tx_body['timestamp'] expected_input.fulfillment.sign(serialize(expected).encode(), SigningKey(user_priv)) expected_ffill = expected_input.fulfillment.serialize_uri() transfer_ffill = transfer_tx_body['fulfillments'][0]['fulfillment'] assert transfer_ffill == expected_ffill transfer_tx = Transaction.from_dict(transfer_tx) assert transfer_tx.fulfillments_valid([tx.conditions[0]]) is True
def test_tx_serialization_with_incorrect_hash(utx): from bigchaindb_common.transaction import Transaction from bigchaindb_common.exceptions import InvalidHash utx_dict = utx.to_dict() utx_dict['id'] = 'abc' with raises(InvalidHash): Transaction.from_dict(utx_dict) utx_dict.pop('id') with raises(InvalidHash): Transaction.from_dict(utx_dict) utx_dict['id'] = [] with raises(InvalidHash): Transaction.from_dict(utx_dict)