def test_valid_transaction_with_invalid_outputs(): sender_wallet = Wallet() transaction = Transaction(sender_wallet, 'reciepient', 50) transaction.output[sender_wallet.address] = 1998 with pytest.raises(Exception, match='Invalid transaction output values'): Transaction.transaction_is_valid(transaction)
def is_valid_transaction_chain(chain): """ Enforce the rules of a chain composed of blocks of transactions - each transaction must only appear once in the chain - There can be only one mining reward per block - Each transaction must be valid """ transaction_ids = set() for i in range(len(chain)): block = chain[i] has_mining_reward = False for transaction_json in block.data: transaction = Transaction.from_json(transaction_json) if transaction.id in transaction_ids: raise Exception(f'Transaction: {transaction.id} is not unique') transaction_ids.add(transaction.id) if transaction.input == MINING_REWARD_INPUT: if has_mining_reward: raise Exception(f'There can be only one mining reward per block check this block: {block.hash}') has_mining_reward = True else: historic_blockchain = Blockchain() historic_blockchain.chain = chain[0:i] historic_balance = Wallet.calculate_balance(historic_blockchain, transaction.input['address']) if historic_balance != transaction.input['amount']: raise Exception(f'Transaction {transaction.id} has '\ 'invalid input amount') Transaction.transaction_is_valid(transaction)
def test_valid_reward_transaction(): reward_transaction = Transaction.reward_transaction(Wallet()) Transaction.transaction_is_valid(reward_transaction)
def test_valid_transaction_with_invalid_signature(): transaction = Transaction(Wallet(), 'reciepient', 50) transaction.input['signature'] = Wallet().sign(transaction.output) with pytest.raises(Exception, match='Invalid signature'): Transaction.transaction_is_valid(transaction)
def test_valid_transaction(): Transaction.transaction_is_valid(Transaction(Wallet(), 'reciepient', 50))
def test_invalid_reward_transaction_invalid_amount(): miner_wallet = Wallet() reward_transaction = Transaction.reward_transaction(miner_wallet) reward_transaction.output[miner_wallet.address] = 1998 with pytest.raises(Exception, match='Invalid Mining Reward'): Transaction.transaction_is_valid(reward_transaction)
def test_invalid_reward_transaction_extra_reciepient(): reward_transaction = Transaction.reward_transaction(Wallet()) reward_transaction.output['extra_reciepient'] = 60 with pytest.raises(Exception, match='Invalid Mining Reward'): Transaction.transaction_is_valid(reward_transaction)