def test_valid_transaction_with_invalid_signature(): trans = Transaction(Wallet(), 'recipient', 50) # Try to update the signature with a new signature that uses a new signed # version of the valid transaction output data. trans.input['signature'] = Wallet().sign(trans.output) with pytest.raises(Exception, match='Invalid Signature'): Transaction.is_valid(trans)
def is_valid_trans_chain(chain): ''' Enforce the rules of a chain composed of blocks of transaction. - Each transaction must only appear ONCE in the chain. - There can only be ONE mining reward per block. - Each transaction MUST be valid. ''' trans_ids = set() for i in range(len(chain)): block = chain[i] has_mining_reward = False for trans_json in block.data: trans = Transaction.from_json(trans_json) if trans.input == MINING_REWARD_INPUT: if has_mining_reward: raise Exception('There can only be one mining reward ' 'per block. Check block with hash: ' f'{block.hash}') has_mining_reward = True else: if trans.id in trans_ids: raise Exception( f'Transaction {trans.id} is not unique.') trans_ids.add(trans.id) historic_blockchain = Blockchain() historic_blockchain.chain = chain[0:i] historic_balance = Wallet.calculate_balance( historic_blockchain, trans.input['address']) if historic_balance != trans.input['amount']: raise Exception( f'Transaction {trans.id} has an invalid input amount.' ) Transaction.is_valid(trans)
def test_valid_transaction_with_invalid_outputs(): sender_wallet = Wallet() trans = Transaction(sender_wallet, 'recipient', 50) trans.output[sender_wallet.address] = 9001 with pytest.raises(Exception, match='Invalid transaction output values'): Transaction.is_valid(trans)
def test_valid_transaction(): Transaction.is_valid(Transaction(Wallet(), 'recipient', 50))
def test_invalid_reward_transaction_invalid_amount(): miner_wallet = Wallet() reward_trans = Transaction.reward_transaction(miner_wallet) reward_trans.output[miner_wallet.address] = 9001 with pytest.raises(Exception, match='Invalid mining reward'): Transaction.is_valid(reward_trans)
def test_invalid_reward_transaction_extra_recipient(): reward_trans = Transaction.reward_transaction(Wallet()) reward_trans.output['extra_recipient'] = 60 with pytest.raises(Exception, match='Invalid mining reward'): Transaction.is_valid(reward_trans)
def test_valid_reward_transaction(): reward_trans = Transaction.reward_transaction(Wallet()) Transaction.is_valid(reward_trans)