Exemple #1
0
def test_blockchain_valid_transaction_duplicate_rewardss():
    blockchain = Blockchain()
    transaction = Transactions(Wallet(), 'recipient', 100).to_json()
    reward_transaction = Transactions.transaction_reward(Wallet()).to_json()
    blockchain.add_block([transaction, reward_transaction, reward_transaction])
    with pytest.raises(Exception, match="has multiple rewards"):
        Blockchain.is_chain_transaction_valid(blockchain.chain)
Exemple #2
0
def test_transactions_validate_invalid_rewards():
    miner_wallet = Wallet()
    reward_transaction = Transactions.transaction_reward(miner_wallet)
    reward_transaction.output[miner_wallet.address] = 100
    reward_transaction.output['recp1'] = 100
    with pytest.raises(Exception, match="Invalid transaction reward"):
        Transactions.verify_transaction(reward_transaction)
def test_wallet_balance_amount():
	wallet = Wallet()
	blockchain = Blockchain()
	amount = 34
	tr1 = Transactions(wallet, 'recp1', amount)
	blockchain.add_block([tr1.to_json()])
	assert Wallet.calculate_balance(blockchain, wallet.address) == STARTING_BALANCE - amount
Exemple #4
0
def blockchain():
    blockchain = Blockchain()
    for i in range(3):
        miner_wallet = Wallet()
        transaction = Transactions(Wallet(), 'recipient', i)
        reward_transaction = Transactions.transaction_reward(miner_wallet)
        blockchain.add_block([transaction.to_json()])
        return blockchain
Exemple #5
0
def test_blockchain_valid_transaction_incorrect_historical_balance(blockchain):
    wallet = Wallet()
    bad_transaction = Transactions(wallet, 'recipient', 1)
    bad_transaction.output[wallet.address] = 9000
    bad_transaction.input['amount'] = 9001
    bad_transaction.input['signature'] = wallet.sign(bad_transaction.output)
    blockchain.add_block([bad_transaction.to_json()])
    with pytest.raises(Exception, match="did not have the correct balance"):
        Blockchain.is_chain_transaction_valid(blockchain.chain)
Exemple #6
0
def make_transaction():
    transaction_json = request.get_json()
    #check if transaction exists
    transaction = transaction_pool.existing_transaction(wallet.address)
    if transaction:
        transaction.update_transaction(wallet, transaction_json['recipient'],
                                       transaction_json['amount'])
    else:
        transaction = Transactions(wallet, transaction_json['recipient'],
                                   transaction_json['amount'])

    #broadcast the transaction object
    pubsub.broadcast_transaction(transaction)
    return jsonify(transaction.to_json())
def test_transaction_clear_transaction():
    transaction_pool = TransactionPool()
    transaction1 = Transactions(Wallet(), 'recp1', 10)
    transaction_pool.set_transaction(transaction1)
    blockchain = Blockchain()
    blockchain.add_block([transaction1.to_json()])
    # assert len(blockchain.chain) > 1
    print(transaction_pool.transaction_map)
    transaction_pool.clear_transaction(blockchain)
    assert transaction1.id not in transaction_pool.transaction_map.keys()
    # for index, block in enumerate(blockchain.chain):
    # 	if index == 0:
    # 		continue
    # 	for tdata in block.data:
    # 		# tdata = ast.literal_eval(tdata)
    # 		assert tdata['id'] == 'str'
Exemple #8
0
def mine_block():
    #get the transaction data and put it into the data field of add_block
    transaction_data = transaction_pool.transaction_data()
    #Append the transaction reward into the wallet of the miner
    transaction_reward = Transactions.transaction_reward(wallet).to_json()
    transaction_data.append(transaction_reward)
    blockchain.add_block(transaction_data)
    block = blockchain.chain[-1]
    #publish the block throughout the network to the subscribed channel
    pubsub.broadcast_block(block)
    #After everytime a block is mined, we need to clear the transaction pool.
    transaction_pool.clear_transaction(blockchain)
    return block.to_json(), 200
    def is_chain_transaction_valid(chain):
        """
		Method to verify if each of the transactions in the chain is valid.
		Transaction is valid if:
		1. Each transation appears only once in the blockchain.
		2. There is only one reward transaction.
		3. The transaction is valid.
		"""
        transaction_ids = set()
        for index, block in enumerate(chain):
            if index == 0:
                continue
            has_reward_transaction = False
            for transaction_json in block.data:
                transaction = Transactions.from_json(transaction_json)
                if transaction.input == MINING_REWARD_INPUT:
                    if has_reward_transaction is True:
                        raise Exception(
                            "Transaction with id %s has multiple rewards" %
                            (transaction.id))
                    has_reward_transaction = True
                else:
                    #calculate historical balance using a historical balance
                    historical_chain = chain[:index]
                    historical_blockchain = Blockchain()
                    historical_blockchain.chain = historical_chain
                    #get the balance amount of the address
                    balance = Wallet.calculate_balance(
                        historical_blockchain, transaction.input['address'])
                    if balance != transaction.input['amount']:
                        raise Exception(
                            "Transaction id %s did not have the correct balance"
                            % (transaction.id))
                if transaction.id in transaction_ids:
                    raise Exception("Transaction with id %s is not unique" %
                                    (transaction.id))
                transaction_ids.add(transaction.id)
                Transactions.verify_transaction(transaction)
 def message(self, pubnub, message_object):
     print('Message channel: %s | Message object: %s' %
           (message_object.channel, message_object.message))
     #check if a block was received through the BLOCK channel and then add it to the chaina and then perform replace chain
     if message_object.channel == 'BLOCK':
         block = Block.from_json(message_object.message)
         potential_chain = self.blockchain.chain[:]
         #add received block to the chain
         potential_chain.append(block)
         #perform replace_chain operation
         try:
             self.blockchain.replace_chain(potential_chain)
             #After everytime a block is mined, we need to clear the transaction pool.
             self.transaction_pool.clear_transaction(self.blockchain)
             print("Chain replacement was successful")
         except Exception as e:
             print("Chain replacement was not successful: %s" % (e))
     elif message_object.channel == 'TRANSACTIONS':
         transaction = Transactions.from_json(message_object.message)
         self.transaction_pool.set_transaction(transaction)
Exemple #11
0
def test_update_same_recp_transactions_invalid():
    wallet = Wallet()
    transactions = Transactions(wallet, 'recp1', 100)
    with pytest.raises(Exception, match="Amount greater than balance"):
        transactions.update_transaction(wallet, 'recp1', 901)
Exemple #12
0
@app.route('/transactions')
def get_all_transactions():
    transaction_data = transaction_pool.transaction_data()
    return jsonify(transaction_data)


ROOT_PORT = 5000
PORT = ROOT_PORT
if os.getenv('PEER'):
    PORT = random.randint(5001, 6000)
    result = requests.get("http://localhost:%s/blockchain" % (ROOT_PORT))
    result_blockchain = Blockchain.from_json(result.json())
    try:
        blockchain.replace_chain(result_blockchain)
        print("Chain replacement with root node was successful")
    except Exception as e:
        print("Chain replacement was not successful: %s" % (e))

#Seed a few data into the backend to help us evaluate the frontend design
if os.getenv('SEED'):
    for i in range(0, 10):
        blockchain.add_block(
            [Transactions(Wallet(),
                          Wallet().address, i).to_json()])
    for i in range(0, 10):
        transaction_pool.set_transaction(
            Transactions(Wallet(),
                         Wallet().address, i))

app.run(port=PORT)
def test_transaction_pool():
    transaction_pool = TransactionPool()
    transaction1 = Transactions(Wallet(), 'recp1', 10)
    transaction_pool.set_transaction(transaction1)
    assert transaction1.id in transaction_pool.transaction_map.keys()
Exemple #14
0
def test_blockchain_valid_transaction_duplicate_transactions():
    blockchain = Blockchain()
    transaction = Transactions(Wallet(), 'recipient', 100).to_json()
    blockchain.add_block([transaction, transaction])
    with pytest.raises(Exception, match="is not unique"):
        Blockchain.is_chain_transaction_valid(blockchain.chain)
Exemple #15
0
def test_transactions_validate_reward():
    miner_wallet = Wallet()
    reward_transaction = Transactions.transaction_reward(miner_wallet)
    Transactions.verify_transaction(reward_transaction)
Exemple #16
0
def test_transactions_basic():
    wallet = Wallet()
    Transactions(wallet, 'recp1', 100)
Exemple #17
0
def test_transactions_reward():
    miner_wallet = Wallet()
    reward_transaction = Transactions.transaction_reward(miner_wallet)
    assert reward_transaction.output[miner_wallet.address] == MINING_REWARD
    assert reward_transaction.input == MINING_REWARD_INPUT
Exemple #18
0
def test_verify_transactions_invalid_signature():
    wallet = Wallet()
    transactions = Transactions(wallet, 'recp1', 100)
    transactions.input['signature'] = Wallet().sign(transactions.output)
    with pytest.raises(Exception, match="Invalid Signature"):
        Transactions.verify_transaction(transactions)
Exemple #19
0
def test_verify_transactions_output_values_wrong():
    wallet = Wallet()
    transactions = Transactions(wallet, 'recp1', 100)
    transactions.input['amount'] = 78
    with pytest.raises(Exception, match="Invalid output values"):
        Transactions.verify_transaction(transactions)
Exemple #20
0
def test_transactions_amt_greater_than_balance():
    wallet = Wallet()
    with pytest.raises(Exception, match="Amount greater than balance"):
        Transactions(wallet, 'recp1', 1001)
Exemple #21
0
def test_update_same_recp_transactions():
    wallet = Wallet()
    transactions = Transactions(wallet, 'recp1', 100)
    transactions.update_transaction(wallet, 'recp1', 100)
Exemple #22
0
def test_verify_transactions():
    wallet = Wallet()
    transactions = Transactions(wallet, 'recp1', 100)
    Transactions.verify_transaction(transactions)
    @staticmethod
    def calculate_balance(blockchain, address):
        """
		Method to calculate the balances of a Wallet given its address.
		If the wallet's address is in the transaction's input, then we set the balance to the amount in input field.
		If the wallet's address is in the transaction's output, then we add the value in output field to the balance. 
		"""
        balance = STARTING_BALANCE
        #handle the scenario where blockchain is None
        if blockchain is None:
            return balance
        for index, block in enumerate(blockchain.chain):
            if index == 0:
                continue
            for transaction in block.data:
                if transaction['input']['address'] == address:
                    balance = transaction['output'][address]
                elif address in transaction['output']:
                    balance = balance + transaction['output'][address]
        return balance


if __name__ == '__main__':
    from backend.wallet.transactions import Transactions
    from backend.blockchain.blockchain import Blockchain
    wallet = Wallet()
    blockchain = Blockchain()
    amount = 34
    tr1 = Transactions(wallet, 'recp1', amount)
    blockchain.add_block([tr1.to_json()])
    print(Wallet.calculate_balance(blockchain, wallet.address))