コード例 #1
0
def test_invalid_reward_transaction_invalid_amount():
    miner_wallet = Wallet()
    reward_transaction = Transaction.reward_transaction(miner_wallet)
    reward_transaction.output[miner_wallet.address] = 9001

    with pytest.raises(Exception, match="INVALID MINING REWARD"):
        Transaction.is_valid_transaction(reward_transaction)
コード例 #2
0
def test_is_valid_transaction_chain_bad_transaction(blockchain_three_blocks):
    bad_transaction = Transaction(Wallet(), 'recipient', 1)
    bad_transaction.input['signature'] = Wallet().sign(bad_transaction.output)
    blockchain_three_blocks.add_block([bad_transaction.to_json()])

    with pytest.raises(Exception):
        Blockchain.is_valid_transaction_chain(blockchain_three_blocks.chain)
コード例 #3
0
def test_valid_transaction_with_invalid_outputs():
    sender_wallet = Wallet()
    transaction = Transaction(sender_wallet, 'recipient', 50)
    transaction.output[sender_wallet.address] = 9001

    with pytest.raises(Exception, match='Invalid transaction output values.'):
        Transaction.is_valid_transaction(transaction)
コード例 #4
0
def test_is_valid_transaction_chain_multiple_rewards(blockchain_three_blocks):
    reward_1 = Transaction.reward_transaction(Wallet()).to_json()
    reward_2 = Transaction.reward_transaction(Wallet()).to_json()

    blockchain_three_blocks.add_block([reward_1, reward_2])

    with pytest.raises(Exception, match='one mining reward per block.'):
        Blockchain.is_valid_transaction_chain(blockchain_three_blocks.chain)
コード例 #5
0
ファイル: test_wallet.py プロジェクト: qadamgahiii/loopcoin
def test_calculate_balance():
    blockchain = Blockchain()
    wallet = Wallet()

    assert Wallet.calculate_balance(blockchain,
                                    wallet.address) == STARTING_BALANCE

    amount = 50
    transaction = Transaction(wallet, 'recipient', amount)
    blockchain.add_block([transaction.to_json()])

    assert Wallet.calculate_balance(
        blockchain, wallet.address) == STARTING_BALANCE - amount

    received_amount_1 = 25
    received_transaction_1 = Transaction(Wallet(), wallet.address,
                                         received_amount_1)

    received_amount_2 = 77
    received_transaction_2 = Transaction(Wallet(), wallet.address,
                                         received_amount_2)

    blockchain.add_block(
        [received_transaction_1.to_json(),
         received_transaction_2.to_json()])

    assert Wallet.calculate_balance(blockchain, wallet.address) == \
        STARTING_BALANCE - amount + received_amount_1 + received_amount_2
コード例 #6
0
def test_is_valid_transaction_chain_bad_historic_balance(
    blockchain_three_blocks):
    wallet = Wallet()
    bad_transaction = Transaction(wallet, 'recipient', 1)
    bad_transaction.output[wallet.address] = 9000
    bad_transaction.input['amount'] = 9001
    bad_transaction.input['signature'] = wallet.sign(bad_transaction.output)

    blockchain_three_blocks.add_block([bad_transaction.to_json()])

    with pytest.raises(Exception, match="has an invalid input amount"):
        Blockchain.is_valid_transaction_chain(blockchain_three_blocks.chain)
コード例 #7
0
def test_set_transaction():
    """Test that a transaction is set into transactions pool"""
    transaction_pool = TransactionPool()
    transaction = Transaction(Wallet(), 'recipient', 1)
    transaction_pool.set_transaction(transaction)

    assert transaction_pool.transaction_map[transaction.id] == transaction
コード例 #8
0
def test_is_valid_transaction_chain_duplicate_transaction(
    blockchain_three_blocks):
    transaction = Transaction(Wallet(), 'recipient', 1).to_json()

    blockchain_three_blocks.add_block([transaction, transaction])

    with pytest.raises(Exception, match='is not unique'):
        Blockchain.is_valid_transaction_chain(blockchain_three_blocks.chain)
コード例 #9
0
def route_blockchain_mine():
    transaction_data = transaction_pool.transaction_data()
    transaction_data.append(Transaction.reward_transaction(wallet).to_json())
    blockchain.add_block(transaction_data)
    block = blockchain.chain[-1]
    pubsub.broadcast_block(block)
    transaction_pool.clear_blockchain_transactions(blockchain)

    return jsonify(block.to_json())
コード例 #10
0
def route_wallet_transact():
    # {'recipient': 'foo', 'amount': 15,}
    transaction_data = request.get_json()
    transaction = transaction_pool.existing_transaction(wallet.address)

    # In python, objects are truthy and falsy.
    # Empty object acts like false.
    # False, None, 0, [], '' ~ FALSE
    if transaction:
        transaction.update(wallet, transaction_data['recipient'],
                           transaction_data['amount'])
    else:
        transaction = Transaction(wallet, transaction_data['recipient'],
                                  transaction_data['amount'])

    print(f'transaction.to_json(): {transaction.to_json()}')

    pubsub.broadcast_transaction(transaction)

    return jsonify(transaction.to_json())
コード例 #11
0
ファイル: blockchain.py プロジェクト: qadamgahiii/loopcoin
    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 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 = 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('There can only be one mining reward per block. '\
                            f'Check block with hash: {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 an invalid '\
                                'input amount')

                Transaction.is_valid_transaction(transaction)
コード例 #12
0
def test_transaction():
    sender_wallet = Wallet()
    recipient = 'recipient'
    amount = 50
    transaction = Transaction(sender_wallet, recipient, amount)

    assert transaction.output[recipient] == amount
    assert transaction.output[
        sender_wallet.address] == sender_wallet.balance - amount

    assert 'timestamp' in transaction.input
    assert transaction.input['amount'] == sender_wallet.balance
    assert transaction.input['address'] == sender_wallet.address
    assert transaction.input['public_key'] == sender_wallet.public_key

    assert Wallet.verify(transaction.input['public_key'], transaction.output,
                         transaction.input['signature'])
コード例 #13
0
ファイル: pubsub.py プロジェクト: qadamgahiii/loopcoin
    def message(self, pubnub, message_object):
        print(
            f'\n-- Channel: {message_object.channel} | Message: {message_object.message}'
        )
        if message_object.channel == CHANNELS['BLOCK']:
            block = Block.deserialize_jsonified_block(message_object.message)
            potential_chain = self.blockchain.chain[:]  #Making copy of existing chain
            potential_chain.append(block)

            try:
                self.blockchain.replace_chain(potential_chain)
                self.transaction_pool.clear_blockchain_transactions(
                    self.blockchain)
                print('\n -- Successfully replaced the local chain.')
            except Exception as e:
                print(f'\n -- Did not replace chain: {e}')
        elif message_object.channel == CHANNELS['TRANSACTION']:
            transaction = Transaction.from_json(message_object.message)
            self.transaction_pool.set_transaction(transaction)
            print('\n -- Set the new transaction in the transaction pool.')
コード例 #14
0
def test_clear_blockchain_transactions():
    transaction_pool = TransactionPool()
    transaction1 = Transaction(Wallet(), 'recipient', 1)
    transaction2 = Transaction(Wallet(), 'recipient', 2)

    transaction_pool.set_transaction(transaction1)
    transaction_pool.set_transaction(transaction2)

    blockchain = Blockchain()
    blockchain.add_block([transaction1.to_json(), transaction2.to_json()])

    assert transaction1.id in transaction_pool.transaction_map
    assert transaction2.id in transaction_pool.transaction_map

    transaction_pool.clear_blockchain_transactions(blockchain)

    assert transaction1.id not in transaction_pool.transaction_map
    assert transaction2.id not in transaction_pool.transaction_map
コード例 #15
0
def test_transaction_updatE():
    sender_wallet = Wallet()
    first_recipient = 'first_recipient'
    first_amount = 50

    transaction = Transaction(sender_wallet, first_recipient, first_amount)

    next_recipient = 'next_recipient'
    next_amount = 75
    transaction.update(sender_wallet, next_recipient, next_amount)

    assert transaction.output[next_recipient] == next_amount
    assert transaction.output[sender_wallet.address] == \
        sender_wallet.balance - first_amount - next_amount
    assert Wallet.verify(transaction.input['public_key'], transaction.output,
                         transaction.input['signature'])

    to_first_again_amount = 25
    transaction.update(sender_wallet, first_recipient, to_first_again_amount)
    assert transaction.output[first_recipient] == \
        first_amount + to_first_again_amount
    assert transaction.output[sender_wallet.address] == \
        sender_wallet.balance - first_amount - next_amount - to_first_again_amount
コード例 #16
0
def blockchain_three_blocks():
    blockchain = Blockchain()
    for i in range(3):
        blockchain.add_block([Transaction(Wallet(), 'recipient', i).to_json()])
    return blockchain
コード例 #17
0
def test_transaction_exceeds_balance():
    with pytest.raises(Exception, match='Amount exceeds balance'):
        Transaction(Wallet(), 'recipient', 9001)
コード例 #18
0
    return jsonify(transaction_pool.transaction_data())


ROOT_PORT = 5000
PORT = ROOT_PORT

if os.environ.get('PEER') == 'True':
    PORT = random.randint(5001, 6000)
    result = requests.get(f'http://localhost:{ROOT_PORT}/blockchain')
    print(f'result.json(): {result.json()}')

    result_blockchain = Blockchain.deserialize_jsonified_chain(result.json())
    try:
        blockchain.replace_chain(result_blockchain.chain)
        print('\n -- Successfully synchronized the local chain.')
    except Exception as e:
        print(f'\n -- Error synchronizing: {e} ')
if os.environ.get('SEED_DATA') == 'True':
    for i in range(10):
        blockchain.add_block([
            Transaction(Wallet(),
                        Wallet().address, random.randint(2, 50)).to_json(),
            Transaction(Wallet(),
                        Wallet().address, random.randint(2, 50)).to_json()
        ])
    for i in range(3):
        transaction_pool.set_transaction(
            Transaction(Wallet(),
                        Wallet().address, random.randint(2, 50)), )

app.run(port=PORT)
コード例 #19
0
def test_transaction_update_exceeds_balance():
    sender_wallet = Wallet()
    transaction = Transaction(sender_wallet, 'recipient', 50)

    with pytest.raises(Exception, match='Amount exceeds balance.'):
        transaction.update(sender_wallet, 'new_recipient', 9000)
コード例 #20
0
def test_invalid_reward_transaction_extra_recipient():
    reward_transaction = Transaction.reward_transaction(Wallet())
    reward_transaction.output['extra_recipient'] = 60

    with pytest.raises(Exception, match="INVALID MINING REWARD"):
        Transaction.is_valid_transaction(reward_transaction)
コード例 #21
0
def test_valid_reward_transaction():
    reward_transaction = Transaction.reward_transaction(Wallet())
    Transaction.is_valid_transaction(reward_transaction)
コード例 #22
0
def test_reward_transaction():
    miner_wallet = Wallet()
    transaction = Transaction.reward_transaction(miner_wallet)

    assert transaction.input == MINING_REWARD_INPUT
    assert transaction.output[miner_wallet.address] == MINING_REWARD
コード例 #23
0
def test_valid_transaction_with_invalid_signature():
    transaction = Transaction(Wallet(), 'recipient', 50)
    transaction.input['signature'] = Wallet().sign(transaction.output)

    with pytest.raises(Exception, match='Invalid signature.'):
        Transaction.is_valid_transaction(transaction)
コード例 #24
0
def test_valid_transaction():
    Transaction.is_valid_transaction(Transaction(Wallet(), 'recipient', 15))