Beispiel #1
0
def test_for_valid_transaction_with_invalid_signature():
    transaction = SystemTransactions(Wallet(), 'recipient', 45)
    transaction.transaction_input['signature'] = Wallet().signature_generation(
        transaction.transaction_output)

    with pytest.raises(Exception, match='The Signature is Invalid'):
        SystemTransactions.positively_validate_transaction(transaction)
def test_for__multiple_rewards_in_is_valid_transaction_chain(three_block_blockchain):
    reward_1 = SystemTransactions.transaction_reward_generation(Wallet()).convert_transaction_data_to_json()
    reward_2 = SystemTransactions.transaction_reward_generation(Wallet()).convert_transaction_data_to_json()
    three_block_blockchain.add_block([reward_1, reward_2])

    with pytest.raises(Exception, match='There can only be one mining reward given per block'):
        Blockchain.transaction_chain_is_valid(three_block_blockchain.chain)
Beispiel #3
0
def test_for_extra_recipient_invalid_transaction():
    reward_transaction = SystemTransactions.transaction_reward_generation(
        Wallet())
    reward_transaction.transaction_output['extra_recipient'] = 60

    with pytest.raises(Exception, match='Mining Reward is Invalid'):
        SystemTransactions.positively_validate_transaction(reward_transaction)
Beispiel #4
0
def test_if_transaction_update_exceeds_balance():
    wallet_for_sender = Wallet()
    transaction = SystemTransactions(wallet_for_sender, 'recipient', 50)

    with pytest.raises(Exception, match='The Amount Exceeds Balance'):
        transaction.transaction_update(wallet_for_sender, 'new_recipient',
                                       9001)
Beispiel #5
0
def test_invalid_reward_transaction_invalid_amount():
    miner_wallet = Wallet()
    reward_transaction = SystemTransactions.transaction_reward_generation(
        miner_wallet)
    reward_transaction.transaction_output[miner_wallet.address] = 9001

    with pytest.raises(Exception, match='Mining Reward is Invalid'):
        SystemTransactions.positively_validate_transaction(reward_transaction)
def test_for_bad_transaction_in_is_valid_transaction_chain(three_block_blockchain):
    bad_transaction = SystemTransactions(Wallet(), 'recipient', 1)
    bad_transaction.transaction_input['signature'] = Wallet().signature_generation(
        bad_transaction.transaction_output)
    three_block_blockchain.add_block([bad_transaction.convert_transaction_data_to_json()])

    with pytest.raises(Exception):
        Blockchain.transaction_chain_is_valid(three_block_blockchain.chain)
Beispiel #7
0
def test_valid_transaction_with_invalid_outputs():
    wallet_for_sender = Wallet()
    transaction = SystemTransactions(wallet_for_sender, 'recipient', 45)
    transaction.transaction_output[wallet_for_sender.address] = 9001

    with pytest.raises(
            Exception,
            match='Invalid Transaction Because the Output Values Are Wrong'):
        SystemTransactions.positively_validate_transaction(transaction)
def test_for_bad_historic_balance_in_is_valid_transaction_chain(three_block_blockchain):
    wallet = Wallet()
    bad_transaction = SystemTransactions(wallet, 'recipient', 1)
    bad_transaction.transaction_output[wallet.address] = 9000
    bad_transaction.transaction_input['amount'] = 9001
    bad_transaction.transaction_input['signature'] = wallet.signature_generation(bad_transaction.transaction_output)

    three_block_blockchain.add_block([bad_transaction.convert_transaction_data_to_json()])

    with pytest.raises(Exception, match='has an invalid input amount'):
        Blockchain.transaction_chain_is_valid(three_block_blockchain.chain)
Beispiel #9
0
def test_for_transaction_rewards():
    miner_wallet = Wallet()
    transaction = SystemTransactions.transaction_reward_generation(
        miner_wallet)

    assert transaction.transaction_input == INPUT_FOR_MINING_REWARD
    assert transaction.transaction_output[
        miner_wallet.address] == THE_MINING_REWARD
Beispiel #10
0
def wallet_transactions_route():
    transaction_data = request.get_json()
    transaction = transaction_pool.existing_transaction(wallet.address)
    if transaction:
        transaction.transaction_update(
            wallet,
            transaction_data['recipient'],
            transaction_data['amount']
        )
    else:   
        transaction = SystemTransactions(
            wallet,
            transaction_data['recipient'],
            transaction_data['amount']
        )

    pubsub.broadcast_transaction(transaction)
    return jsonify(transaction.convert_transaction_data_to_json())
Beispiel #11
0
    def transaction_chain_is_valid(chain):
        """
        This section deals with enforcing rules of a chain made up 
        of blocks of transactions. The following must apply:
            - Each transaction must only appear once in the chain.
            - There can only be 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 = SystemTransactions.convert_transaction_data_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.transaction_input == INPUT_FOR_MINING_REWARD:
                    if has_mining_reward:
                        raise Exception(
                            'There can only be one mining reward given per block.'\
                            f'Check block with the hash: {block.hash}'
                        )
                    has_mining_reward = True  
                else:
                    historic_blockchain = Blockchain()
                    historic_blockchain.chain = chain[0:i]
                    historic_balance = Wallet.wallet_balance_calculation(
                        historic_blockchain,
                        transaction.transaction_input['address']
                    )

                    if historic_balance != transaction.transaction_input['amount']:
                        raise Exception(
                            f'Transaction {transaction.id} has an invalid '\
                            'input amount'
                        )

                SystemTransactions.positively_validate_transaction(transaction)      
Beispiel #12
0
def blockchain_mine_route():
    transaction_data = transaction_pool.transaction_of_data()
    transaction_data.append(SystemTransactions.transaction_reward_generation(wallet).convert_transaction_data_to_json())
    
    blockchain.add_block(transaction_data)
    block = blockchain.chain[-1]
    pubsub.block_broadcast(block)
    transaction_pool.clear_the_blockchain_transactions(blockchain)

    return jsonify(block.convert_block_to_json())
Beispiel #13
0
def test_for_transaction_update():
    wallet_for_sender = Wallet()
    first_recipient = 'first_recipient'
    first_amount_sent = 45
    transaction = SystemTransactions(wallet_for_sender, first_recipient,
                                     first_amount_sent)

    next_recipient = 'next_recipient'
    next_amount_sent = 70
    transaction.transaction_update(wallet_for_sender, next_recipient,
                                   next_amount_sent)

    assert transaction.transaction_output[next_recipient] == next_amount_sent
    assert transaction.transaction_output[wallet_for_sender.address] ==\
        wallet_for_sender.wallet_balance - first_amount_sent - next_amount_sent
    assert Wallet.verify_signature(transaction.transaction_input['public_key'],
                                   transaction.transaction_output,
                                   transaction.transaction_input['signature'])

    amount_resend_to_first_recipient = 30
    transaction.transaction_update(wallet_for_sender, first_recipient,
                                   amount_resend_to_first_recipient)

    assert transaction.transaction_output[first_recipient] == \
        first_amount_sent + amount_resend_to_first_recipient
    assert transaction.transaction_output[wallet_for_sender.address] ==\
        wallet_for_sender.wallet_balance - first_amount_sent - next_amount_sent - amount_resend_to_first_recipient
    assert Wallet.verify_signature(transaction.transaction_input['public_key'],
                                   transaction.transaction_output,
                                   transaction.transaction_input['signature'])
Beispiel #14
0
def test_transaction():
    wallet_for_sender = Wallet()
    recipient = 'recipient'
    amount = 50
    transaction = SystemTransactions(wallet_for_sender, recipient, amount)

    assert transaction.transaction_output[recipient] == amount
    assert transaction.transaction_output[
        wallet_for_sender.address] == wallet_for_sender.wallet_balance - amount

    assert 'timestamp' in transaction.transaction_input
    assert transaction.transaction_input[
        'amount'] == wallet_for_sender.wallet_balance
    assert transaction.transaction_input[
        'address'] == wallet_for_sender.address
    assert transaction.transaction_input[
        'public_key'] == wallet_for_sender.public_key

    assert Wallet.verify_signature(transaction.transaction_input['public_key'],
                                   transaction.transaction_output,
                                   transaction.transaction_input['signature'])
Beispiel #15
0
    def message(self, pubnub, message_object):
        print(
            f'\n-- Channel: {message_object.channel} | Message : {message_object.message}'
        )

        if message_object.channel == COMMUNICATION_CHANNELS['BLOCK']:
            block = Block.convert_block_from_json(message_object.message)
            potential_chain = self.blockchain.chain[:]
            potential_chain.append(block)

            try:
                self.blockchain.replace_the_chain(potential_chain)
                self.transaction_pool.clear_the_blockchain_transactions(
                    self.blockchain)
                print('\n -- The local chain was replaced succesfully')
            except Exception as e:
                print(f'\n -- Unfortunately, the chain was not replaced: {e}')
        elif message_object.channel == COMMUNICATION_CHANNELS['TRANSACTION']:
            transaction = SystemTransactions.convert_transaction_data_from_json(
                message_object.message)
            self.transaction_pool.setting_the_trasaction(transaction)
            print(
                '\n -- The New Transaction has Been Set in the Transaction Pool'
            )
Beispiel #16
0
def test_clear_blockchain_transactions():
    transaction_pool = TransactionPool()
    transac_number_1 = SystemTransactions(Wallet(), 'recipient', 1)
    transac_number_2 = SystemTransactions(Wallet(), 'recipient', 2)

    transaction_pool.setting_the_trasaction(transac_number_1)
    transaction_pool.setting_the_trasaction(transac_number_2)

    blockchain = Blockchain()
    blockchain.add_block([
        transac_number_1.convert_transaction_data_to_json(),
        transac_number_2.convert_transaction_data_to_json()
    ])

    assert transac_number_1.id in transaction_pool.map_of_transactions
    assert transac_number_2.id in transaction_pool.map_of_transactions

    transaction_pool.clear_the_blockchain_transactions(blockchain)

    assert not transac_number_1.id in transaction_pool.map_of_transactions
    assert not transac_number_2.id in transaction_pool.map_of_transactions
def test_for_duplicate_transactions_in_is_valid_transaction_chain(three_block_blockchain):
    transaction = SystemTransactions(Wallet(), 'recipient', 1).convert_transaction_data_to_json()
    three_block_blockchain.add_block([transaction, transaction])

    with pytest.raises(Exception, match='is not unique'):
        Blockchain.transaction_chain_is_valid(three_block_blockchain.chain)
def three_block_blockchain():
    blockchain = Blockchain()
    for i in range(3):
        blockchain.add_block([SystemTransactions(Wallet(), 'recipient', i).convert_transaction_data_to_json()])
    return blockchain
Beispiel #19
0
def test_set_transaction():
    transaction_pool = TransactionPool()
    transaction = SystemTransactions(Wallet(), 'recipient', 1)
    transaction_pool.setting_the_trasaction(transaction)

    assert transaction_pool.map_of_transactions[transaction.id] == transaction
Beispiel #20
0
def test_for_valid_transaction():
    SystemTransactions.positively_validate_transaction(
        SystemTransactions(Wallet(), 'recipient', 50))
Beispiel #21
0
def test_if_transaction_exceeds_balance():
    with pytest.raises(Exception, match='The Amount Exceeds Balance'):
        SystemTransactions(Wallet(), 'recipient', 9001)
Beispiel #22
0
def test_for_valid_reward_transaction():
    reward_transaction = SystemTransactions.transaction_reward_generation(
        Wallet())
    SystemTransactions.positively_validate_transaction(reward_transaction)