def validate_block(bigchain, block): """Validate a block. Args: bigchain (Bigchain): an instantiated bigchaindb.Bigchain object. block (dict): block to validate. Returns: The block if the block is valid else it raises an exception describing the reason why the block is invalid. Raises: InvalidHash: if the hash of the block is wrong. """ # Check if current hash is correct calculated_hash = crypto.hash_data(util.serialize(block['block'])) if calculated_hash != block['id']: raise exceptions.InvalidHash() # Check if the block was created by a federation node if block['block']['node_pubkey'] not in (bigchain.nodes_except_me + [bigchain.me]): raise exceptions.OperationError( 'Only federation nodes can create blocks') # Check if block signature is valid verifying_key = crypto.VerifyingKey(block['block']['node_pubkey']) if not verifying_key.verify(util.serialize(block['block']), block['signature']): raise exceptions.InvalidSignature('Invalid block signature') return block
def check_hash_and_signature(transaction): # Check hash of the transaction calculated_hash = get_hash_data(transaction) if calculated_hash != transaction['id']: raise exceptions.InvalidHash() # Check signature if not validate_fulfillments(transaction): raise exceptions.InvalidSignature()
def check_hash_and_signature(transaction): # Check hash of the transaction calculated_hash = hash_data(serialize(transaction['transaction'])) if calculated_hash != transaction['id']: raise exceptions.InvalidHash() # Check signature if not verify_signature(transaction): raise exceptions.InvalidSignature()
def validate_transaction(bigchain, transaction): """Validate a transaction. Args: bigchain (Bigchain): an instantiated bigchaindb.Bigchain object. transaction (dict): transaction to validate. Returns: The transaction if the transaction is valid else it raises an exception describing the reason why the transaction is invalid. Raises: OperationError: if the transaction operation is not supported TransactionDoesNotExist: if the input of the transaction is not found TransactionOwnerError: if the new transaction is using an input it doesn't own DoubleSpend: if the transaction is a double spend InvalidHash: if the hash of the transaction is wrong InvalidSignature: if the signature of the transaction is wrong """ # If the operation is CREATE the transaction should have no inputs and # should be signed by a federation node if transaction['transaction']['operation'] == 'CREATE': if transaction['transaction']['input']: raise ValueError('A CREATE operation has no inputs') if transaction['transaction']['current_owner'] not in ( bigchain.federation_nodes + [bigchain.me]): raise exceptions.OperationError( 'Only federation nodes can use the operation `CREATE`') else: # check if the input exists, is owned by the current_owner if not transaction['transaction']['input']: raise ValueError( 'Only `CREATE` transactions can have null inputs') tx_input = bigchain.get_transaction( transaction['transaction']['input']) 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'])) # check if the input was already spent by a transaction other than # this one. spent = bigchain.get_spent(tx_input['id']) if spent and spent['id'] != transaction['id']: raise exceptions.DoubleSpend( 'input `{}` was already spent'.format( transaction['transaction']['input'])) # Check hash of the transaction calculated_hash = crypto.hash_data( util.serialize(transaction['transaction'])) if calculated_hash != transaction['id']: raise exceptions.InvalidHash() # Check signature if not util.verify_signature(transaction): raise exceptions.InvalidSignature() return transaction
def validate_transaction(bigchain, transaction): """Validate a transaction. Args: bigchain (Bigchain): an instantiated bigchaindb.Bigchain object. transaction (dict): transaction to validate. Returns: The transaction if the transaction is valid else it raises an exception describing the reason why the transaction is invalid. Raises: OperationError: if the transaction operation is not supported TransactionDoesNotExist: if the input of the transaction is not found TransactionOwnerError: if the new transaction is using an input it doesn't own DoubleSpend: if the transaction is a double spend InvalidHash: if the hash of the transaction is wrong InvalidSignature: if the signature of the transaction is wrong """ # If the operation is CREATE the transaction should have no inputs and # should be signed by a federation node if transaction['transaction']['operation'] == 'CREATE': # TODO: for now lets assume a CREATE transaction only has one fulfillment if transaction['transaction']['fulfillments'][0]['input']: raise ValueError('A CREATE operation has no inputs') # TODO: for now lets assume a CREATE transaction only has one current_owner if transaction['transaction']['fulfillments'][0]['current_owners'][ 0] not in (bigchain.nodes_except_me + [bigchain.me]): raise exceptions.OperationError( 'Only federation nodes can use the operation `CREATE`') else: # check if the input exists, is owned by the current_owner if not transaction['transaction']['fulfillments']: raise ValueError('Transaction contains no fulfillments') # check inputs for fulfillment in transaction['transaction']['fulfillments']: if not fulfillment['input']: raise ValueError( 'Only `CREATE` transactions can have null inputs') tx_input = bigchain.get_transaction( fulfillment['input']['txid']) if not tx_input: raise exceptions.TransactionDoesNotExist( 'input `{}` does not exist in the bigchain'.format( fulfillment['input']['txid'])) # TODO: check if current owners own tx_input (maybe checked by InvalidSignature) # check if the input was already spent by a transaction other than # this one. spent = bigchain.get_spent(fulfillment['input']) if spent and spent['id'] != transaction['id']: raise exceptions.DoubleSpend( 'input `{}` was already spent'.format( fulfillment['input'])) # Check hash of the transaction calculated_hash = util.get_hash_data(transaction) if calculated_hash != transaction['id']: raise exceptions.InvalidHash() # Check fulfillments if not util.validate_fulfillments(transaction): raise exceptions.InvalidSignature() return transaction