def test_mining_block():
    node_id = uuid4()
    w = Wallet(test=True)
    chain = Blockchain(w.address, node_id, is_test=True)
    assert Verification.verify_chain(chain.chain)
    chain.mine_block()
    assert Verification.verify_chain(chain.chain)
    chain.mine_block()
    assert Verification.verify_chain(chain.chain)
def test_mining_block_with_open_transactions():
    timestamp = datetime.utcfromtimestamp(0)
    node_id = uuid4()
    w1 = Wallet(test=True)
    w2 = Wallet(test=True)

    chain = Blockchain(w1.address, node_id, difficulty=1, is_test=True)

    tx_details_1 = Details(
        sender=w1.address,
        recipient=w2.address,
        nonce=0,
        amount=0.5,
        timestamp=timestamp,
        public_key=w1.public_key.hex(),
    )
    transaction_1 = w1.sign_transaction(tx_details_1)

    tx_details_2 = Details(
        sender=w2.address,
        recipient=w1.address,
        nonce=0,
        amount=0.5,
        timestamp=timestamp,
        public_key=w2.public_key.hex(),
    )
    transaction_2 = w2.sign_transaction(tx_details_2)

    assert Verification.verify_chain(chain.chain)
    # Need to give the w1 at least 1.0 coin in their balance
    chain.mine_block()
    assert Verification.verify_chain(chain.chain)
    chain.add_transaction(transaction_1, is_receiving=True)
    chain.mine_block()
    assert Verification.verify_chain(chain.chain)
    chain_transactions = []
    for block in chain.chain:
        for tx in block.transactions:
            chain_transactions.append(tx)
    assert Verification.hash_transaction(transaction_1) in chain_transactions
    chain.add_transaction(transaction_2, is_receiving=True)
    chain.mine_block()
    chain_transactions = []
    for block in chain.chain:
        for tx in block.transactions:
            chain_transactions.append(tx)
    assert Verification.hash_transaction(transaction_2) in chain_transactions
Пример #3
0
    def listen(self):
        waiting_for_input = True


        while waiting_for_input:
            print('Please choose')
            print('1: Add a new transaction value')
            print('2: Mine a new block')
            print('3: Output the blockchain blocks')
            print('4: Check transaction validity')
            print('5: Create wallet')
            print('6: Load wallet')
            print('7: Save keys')
            print('q: Quit')

            user_choice = input('Selection: ')

            if user_choice == '1':
                tx_data = self.get_transaction_value()
                recipient, amount = tx_data
                if self.blockchain.add_transaction(recipient, self.id, amount=amount):
                    print('Transaction Added')
                else:
                    print('Transaction Failed')
                print(self.blockchain.open_transactions)
            elif user_choice == '2':
                self.blockchain.mine_block()
            elif user_choice == '3':
                self.print_blockchain_elements()
            elif user_choice == '4':
                if Verification.verify_transactions(self.blockchain.open_transactions, self.blockchain.get_balance):
                    print('All transactions valid')
                else:
                    print('Invalid transaction found!')
                    print('Exiting!')
                    break
            elif user_choice == '5':
                self.wallet.create_keys()
                self.blockchain = Blockchain(self.wallet.public_key)
            elif user_choice == '6':
                self.wallet.load_keys()
                self.blockchain = Blockchain(self.wallet.public_key)
            elif user_choice == '7':
                self.wallet.save_keys()
            elif user_choice == 'q':
                waiting_for_input = False
            else:
                print('Input was invalid, please pick a value from the list!')
            if not Verification.verify_chain(self.blockchain.chain):
                self.print_blockchain_elements()
                print('Invalid blockchain!')
                break
            print()
            print('Balance of {}: {:6.4f}'.format(self.wallet.public_key, self.blockchain.get_balance()))
        else:
            print('User left!')

        print('Done!')
Пример #4
0
    def listen_for_input(self):
        waiting_for_input = True
        while waiting_for_input:
            print('Please choose')
            print('1: Add a new transaction value')
            print('2: Mine a new block')
            print('3: Output the blockchain blocks')
            print('4: Check transaction validity')
            # print('h: Manipulate the chain')
            print('q: Quit')
            user_choice = self.get_user_choice()
            if user_choice == '1':
                tx_data = self.get_transaction_value()
                recipient, amount = tx_data
                if self.blockchain.add_transaction(recipient,
                                                   self.id,
                                                   amount=amount):
                    print('Added transaction!')
                else:
                    print('Transaction failed!')
                print(self.blockchain.open_transactions)
            elif user_choice == '2':
                self.blockchain.mine_block()
            elif user_choice == '3':
                self.print_blockchain_elements()
            elif user_choice == '4':
                v = Verification()
                if v.verify_transactions(self.blockchain.open_transactions,
                                         self.blockchain.get_balance):
                    print('All transactions are valid')
                else:
                    print('There are invalid transactions')
            # elif user_choice == 'h':
            #     if len(blockchain) >= 1:
            #         blockchain[0] = {
            #             'previous_hash': '',
            #             'index': 0,
            #             'transactions': [{
            #                 'sender': 'Chris',
            #                 'recipient': 'Will',
            #                 'amount': 100.0
            #             }]
            #         }
            elif user_choice == 'q':
                waiting_for_input = False
            else:
                print('Input was invalid, please pick a value from the list!')
            v = Verification()
            if not v.verify_chain(self.blockchain.chain):
                self.print_blockchain_elements()
                print('Invalid blockchain!')
                break
            print('Balance of {}: {:6.2f}'.format(
                self.id, self.blockchain.get_balance()))
        else:
            print('User left!')

        print('Done!')
Пример #5
0
    def listen_for_input(self):
        awaiting_input = True
        while awaiting_input:
            print("Please choose:")
            print("1: Add a new transaction value")
            print("2: Mine a new block")
            print("3: Output the blockchain blocks")
            print("4: Check transaction validity")
            print("q: Quit")
            user_choice = self.get_user_choice()
            if user_choice == "1":
                tx_data = self.get_transaction_value()
                # one possibility is to unpack the tuple by following where the first element of the tuple will be assigned to the first variable (recipient):
                recipient, amount = tx_data
                # second possibility is to call the respective elements directly as argument as following:
                # add_transaction(owner, tx_data[0], tx_data[1])

                # skip the optional sender argument my having a named argument of amount
                #I can check it like that with if since add_transaction returns either True or False
                if self.blockchain.add_transaction(recipient,
                                                   self.id,
                                                   amount=amount):
                    print("Successfully added a transaction!")
                else:
                    print("Transaction failed!")
                print(self.blockchain.open_transactions)
            elif user_choice == "2":
                #reset the block when successful mined since the transactions are then already processed and shouldn't be processed again
                self.blockchain.mine_block()
            elif user_choice == "3":
                self.print_blockchain_output()
            elif user_choice == "4":
                verifier = Verification()
                if verifier.verify_transactions(
                        self.blockchain.open_transactions,
                        self.blockchain.get_balance):
                    print('All transactions are valid')
                else:
                    print('There are invalid transactions')
            elif user_choice == "q":
                awaiting_input = False
            else:
                print(
                    "Input was invalid, please pick one of the values 1 or 2.")
            """
            Check if results of verify_chain (from the returned is_valid) is not True 
            --> because "if verify_chain()" would check if True, which we would need if we want to continue, 
            but here we want to have the case that in case it's false we want to exit the loop
            """
            verifier = Verification()
            if not verifier.verify_chain(self.blockchain.chain):
                self.print_blockchain_output()
                print("Invalid blockchain!")
                break
            print('Balance of {}:{:6.2f}'.format(
                self.id, self.blockchain.get_balance()))

        print("done!")
Пример #6
0
    def listen_for_input(self):
        waiting_for_input = True

        while waiting_for_input:
            print("Please Select:")
            print("1. Enter the transaction amount.")
            print("2. Mine a new block.")
            print("3. Output the blockchain block")
            print("4. Check transaction validity")
            print("q. Quit")
            user_choice = self.get_user_choice()
            print()

            if user_choice == '1':
                tx_data = self.get_transaction_value()
                recipient, amount = tx_data
                # Add the transaction amount to the blockchain.
                if self.blockchain.add_transaction(recipient,
                                                   sender=self.id,
                                                   amount=amount):
                    print("Added Transaction!!")
                else:
                    print("Transaction Failed!")
                print(self.blockchain.get_open_transaction())

            elif user_choice == '2':
                self.blockchain.mine_block()

            elif user_choice == '3':
                self.print_blockchian_elements()

            elif user_choice == '4':
                if Verification.verify_transactions(
                        self.blockchain.get_open_transaction(),
                        self.blockchain.get_balance):
                    print('All transactions are valid!')
                else:
                    print('There are invalid transactions!')

            elif user_choice == 'q':
                waiting_for_input = False

            else:
                print("Invalid Input!!")
                print("Exiting after printing the blocks")
                self.print_blockchian_elements()
                break

            if not Verification.verify_chain(self.blockchain.get_chain()):
                self.print_blockchian_elements()
                print("Invalid Blockchain!")
                break

            print('Balance of {}: {:6.4f}'.format(
                self.id, self.blockchain.get_balance()))
        else:
            print("User Logged Out!")
Пример #7
0
    def listen_for_input(self):
        waiting_for_input = True

        # A while loop for the user input interface
        # It's a loop that exits once waiting_for_input becomes False or when break is called
        while waiting_for_input:
            print('Please choose')
            print('1: Add a new transaction value')
            print('2: Mine a new block')
            print('3: Output the blockchain blocks')
            print('4: Check transaction validity')
            print('q: Quit')
            user_choice = self.get_user_choice()
            if user_choice == '1':
                tx_data = self.get_transaction_value()
                recipient, amount = tx_data
                # Add the transaction amount to the blockchain
                if self.blockchain.add_transaction(recipient,
                                                   self.id,
                                                   amount=amount):
                    print('Added transaction!')
                else:
                    print('Transaction failed!')
                print(self.blockchain.open_transactions)
            elif user_choice == '2':
                self.blockchain.mine_block()
            elif user_choice == '3':
                self.print_blockchain_elements()
            elif user_choice == '4':
                verifier = Verification()
                if verifier.verify_transactions(
                        self.blockchain.open_transactions,
                        self.blockchain.get_balance):
                    print('All transactions are valid')
                else:
                    print('There are invalid transactions')
            elif user_choice == 'q':
                # This will lead to the loop to exist because it's running condition becomes False
                waiting_for_input = False
            else:
                print('Input was invalid, please pick a value from the list!')
            verifier = Verification()
            if not verifier.verify_chain(self.blockchain.chain):
                self.print_blockchain_elements()
                print('Invalid blockchain!')
                # Break out of the loop
                break
            print('Balance of {}: {:6.2f}'.format(
                self.id, self.blockchain.get_balance()))
        else:
            print('User left!')

        print('Done!')
Пример #8
0
    def listen_for_input(self):
        while True:
            print('Please choose')
            print('1: Add a new transcation value')
            print('2: Mine a new block')
            print('3: Output the blockchain blocks')
            print('4: Check transaction validity')
            print('5: Create wallet')
            print('6: Load wallet')
            print('7: Save wallet')
            print('q: Quit')
            user_choice = self.get_user_choice()
            if user_choice == '1':
                tx_data = self.get_transaction_value()
                recipient, amount = tx_data
                signature = self.wallet.sign_transaction(self.wallet.public_key, recipient, amount)
                if self.blockchain.add_transaction(recipient, self.wallet.public_key, signature, amount=amount):
                    print('Added transaction!')
                else:
                    print('Transaction failed!')
                print(self.blockchain.get_open_tx())
            elif user_choice == '2':
                if not self.blockchain.mine_block():
                    print('No wallet, mining failed!')
            elif user_choice == '3':
                self.print_blockchain_elements()
            elif user_choice == '4':
                if Verification.verify_transactions(self.blockchain.get_open_tx(), self.blockchain.get_balance):
                    print('All transactions are valid')
                else:
                    print('There is invalid transaction')
            elif user_choice == '5':
                self.wallet.create_key()
                self.blockchain = Blockchain(self.wallet.public_key)
            elif user_choice == '6':
                self.wallet.load_keys()
                self.blockchain = Blockchain(self.wallet.public_key)
            elif user_choice == '7':
                self.wallet.save_keys()
            elif user_choice == 'q':
                break
            else:
                print('Input was invalid')
            if not Verification.verify_chain(self.blockchain.get_chain()):
                self.print_blockchain_elements()
                print('Invalid blockchain!')
                break
            print('Balacne of {}: {:6.2f}'.format(self.wallet.public_key, self.blockchain.get_balance()))
        else:
            print('User left!')

        print('Done!')
def test_broadcasting_block():
    timestamp = datetime.utcfromtimestamp(0)
    node_id = uuid4()
    w1 = Wallet(test=True)
    w2 = Wallet(test=True)

    chain1 = Blockchain(w1.address, node_id, difficulty=1, is_test=True)
    chain2 = Blockchain(w2.address, node_id, difficulty=1, is_test=True)

    chain2.chain = chain1.chain
    assert chain1.chain == chain2.chain

    details = Details(
        sender=w1.address,
        recipient=w2.address,
        nonce=0,
        amount=0.5,
        timestamp=timestamp,
        public_key=w1.public_key.hex(),
    )
    transaction_1 = w1.sign_transaction(details)

    assert Verification.verify_chain(chain1.chain)
    b = chain1.mine_block()

    result, _ = chain2.add_block(b)
    assert result

    assert Verification.verify_chain(chain1.chain)
    assert Verification.verify_chain(chain2.chain)

    chain1.add_transaction(transaction_1, is_receiving=True)
    chain1.mine_block()
    chain2.add_block(chain1.last_block)

    assert Verification.verify_chain(chain1.chain)
    assert Verification.verify_chain(chain2.chain)

    assert chain1.chain == chain2.chain
Пример #10
0
    def listen_for_input(self):
        waiting_for_input = True
        while waiting_for_input:
            print('Please choose')
            print('1: Add a new transaction value')
            print('2: Mine a new block')
            print('3: Output the blockchain blocks')
            print('4: Check transaction validity')
            print('q: Quit')
            user_choice = self.get_user_choice()
            if user_choice == '1':
                tx_data = self.get_transaction_value()
                recipient, amount = tx_data
                if self.blockchain.add_transaction(recipient,
                                                   self.id,
                                                   amount=amount):
                    print('Added transaction!')
                else:
                    print('Transaction failed!')
                print(self.blockchain.get_open_transactions())
            elif user_choice == '2':
                self.blockchain.mine_block()
            elif user_choice == '3':
                self.print_blockchain_elements()
            elif user_choice == '4':
                if Verification.verify_transactions(
                        self.blockchain.get_open_transactions(),
                        self.blockchain.get_balance):
                    print('All transactions are valid')
                else:
                    print('There are invalid transactions')
            # elif user_choice == 'h':
            #     if len(blockchain) >= 1:
            #         blockchain[0] = {
            #         'previous_hash': hashed_block,
            #         'index': len(blockchain),
            #         'transactions': [{'sender': 'Chris', 'recipient': 'Max', 'amount': 100.0}]
            #         }
            elif user_choice == 'q':
                waiting_for_input = False
            else:
                raise (ValueError(
                    'Input was invalid, please pick a value from the list!'))

            print('Choice registered!')
            if not Verification.verify_chain(self.blockchain.blockchain):
                self.print_blockchain_elements()
                print('Invalid blockchain')
                break
            print(self.blockchain.get_balance())
        print('Done!')
Пример #11
0
    def listen_for_input(self):
        """ allows user to input choices and complete actions on the blockchain """
        waiting_for_input = True

        while waiting_for_input:
            print('Please choose')
            print('1: Add a new transaction value')
            print('2: Mine a new block')
            print('3: Output the blockchain blocks')
            print('4: Check transaction validity')
            print('q: quit')
            user_choice = self.get_user_choice()
            if user_choice == '1':
                tx_data = self.get_transaction_value()
                recipient, amount = tx_data
                if self.blockchain.add_transaction(recipient,
                                                   self.id,
                                                   amount=amount):
                    print('Added transaction!')
                else:
                    print('Transaction failed!')
                print(self.blockchain.get_open_transactions())
            elif user_choice == '2':
                self.blockchain.mine_block()
            elif user_choice == '3':
                self.print_blockchain_elements()
            elif user_choice == '4':
                if Verification.verify_transactions(
                        self.blockchain.get_open_transactions(),
                        self.blockchain.get_balance):
                    print('All transactions are valid!')
                else:
                    print('There are invalid transactions!')
            elif user_choice == 'q':
                waiting_for_input = False
            else:
                print('Input was invalid, please pick a value from the list!')
            if not Verification.verify_chain(self.blockchain.chain):
                self.print_blockchain_elements()
                print('Invalid blockchain!')
                break
            print('Balance of {}: {:6.2f}'.format(
                self.id, self.blockchain.get_balance()))
        else:
            print('User left!')

        print('Done!')
Пример #12
0
    def listen_for_input(self):
        continue_loop = True

        while continue_loop:
            print('1. Add new transaction')
            print('2. Mine new block')
            print('3. Print blockchain')
            print('4. Check transactions')
            print('0. Exit')

            choice = self.get_user_input()

            if choice == 1:
                tx_data = self.get_transaction_value()
                recipient, amount = tx_data
                if self.blockchain.add_transaction(recipient=recipient,
                                                   sender=self.node_id,
                                                   amount=amount):
                    print('Added transaction.')
                else:
                    print('Transaction failed.')
                print(self.blockchain.get_open_transactions())
            elif choice == 2:
                if self.blockchain.mine_block():
                    self.blockchain.save_data()
            elif choice == 3:
                self.print_blockchain()
            elif choice == 4:
                if Verification.check_transactions(
                        self.blockchain.get_open_transactions(),
                        self.blockchain.get_balance):
                    print('All transactions are valid.')
                else:
                    print('There are invalid transactions.')
            elif choice == 0:
                continue_loop = False
            else:
                print('Invalid choice. Please enter 1 - 3')

            if not Verification.verify_chain(self.blockchain.chain):
                print('Chain is invalid')
                break

            print('Balance of {} is {:6.2f}'.format(
                self.node_id, self.blockchain.get_balance(self.node_id)))
        else:
            print('Goodbye')
Пример #13
0
    def listen_for_input(self):
        waiting_for_input = True

        while waiting_for_input:
            print('Please choose:')
            print('1: Add new transaction.')
            print('2: Mine a new block.')
            print('3: Output the blockchain blocks.')
            print('4: Check transaction validity.')
            print('q: Exit')

            user_choice = self.get_input()
            if user_choice == '1':
                tx_data = self.get_transaction_value()
                recipient, amount = tx_data
                if self.blockchain.add_transaction(recipient,
                                                   self.id,
                                                   amount=amount):
                    print('Added transaction!')
                else:
                    print('Transaction failed!!!')
                print(self.blockchain.get_open_transactions())
            elif user_choice == '2':
                self.blockchain.mine_block()
            elif user_choice == '3':
                self.output_blockchain()
            elif user_choice == '4':
                if Verification.verify_transactions(
                        self.blockchain.get_open_transactions(),
                        self.blockchain.get_balance):
                    print('All transactions are valid.')
                else:
                    print('There are invalid transactions.')
            elif user_choice == 'q':
                waiting_for_input = False
            else:
                print('Invalid option. \n')
            if not Verification.verify_chain(self.blockchain.get_chain()):
                self.output_blockchain()
                print('Invalid blockchain!')
                waiting_for_input = False
            print("{}'s balance: {:6.2f} \n".format(
                self.id, self.blockchain.get_balance()))
        print('Done!')
def test_not_enough_coin():
    timestamp = datetime.utcfromtimestamp(0)
    node_id = uuid4()
    w = Wallet(test=True)
    w2 = Wallet(test=True)
    chain = Blockchain(w.address, node_id, difficulty=1, is_test=True)
    tx_details = Details(
        sender=w.address,
        recipient=w2.address,
        nonce=0,
        amount=2995.0,
        timestamp=timestamp,
        public_key=w.public_key.hex(),
    )
    transaction = w.sign_transaction(tx_details)

    assert Verification.verify_chain(chain.chain)
    try:
        chain.add_transaction(transaction, is_receiving=True)
        assert "This was expected to throw a ValueError exception but didn't"
    except ValueError:
        pass
Пример #15
0
 def resolve(self):
     winner_chain = self.chain
     replace = False
     for node in self.__peer_nodes:
         url = 'http://{}/chain'.format(node)
         try:
             response = requests.get(url)
             node_chain = response.json()
             node_chain = [Block(block['index'], block['previous_hash'], [Transaction(
                     tx['sender'], tx['recipient'], tx['signature'], tx['amount']) for tx in block['transactions']],
                 block['proof'], block['timestamp']) for block in node_chain]
             node_chain_length = len(node_chain)
             local_chain_length = len(winner_chain)
             if node_chain_length > local_chain_length and Verification.verify_chain(node_chain):
                 winner_chain = node_chain
                 replace = True
         except requests.exceptions.ConnectionError:
             continue
     self.resolve_conflicts = False
     self.chain = winner_chain
     if replace:
         self.__open_transactions = []
     self.save_data()
     return replace
Пример #16
0
        node.blockchain.resolve()
        return jsonify(response), 200
    else:
        response = {
            'message': 'Blockchain seems to be shorter, block not added'}
        node.blockchain.sync(block)
        return jsonify(response), 409

if __name__=='__main__':
    from argparse import ArgumentParser
    parser = ArgumentParser()
    parser.add_argument('-p', '--port', type=int, default=5000)
    args = parser.parse_args()
    port = args.port
    t1=threading.Thread(target=start_node, args=(port,))
    t1.daemon = True
    t1.start()
    verifier=Verification()
    Nkey=Key()
    #Nkey.assign_key()
    node=Node(Nkey.key)
    if not verifier.verify_chain(node.blockchain.get_chain()):
        print("\nInvalid Blockchain!! Exiting.....\n")
        exit()
    node.listen_input()
    node.blockchain.save_data()
    exit()
    
    

Пример #17
0
 def listen_for_input(self):
     waiting_for_input = True
     # A while loop for the user input interface
     # It's a loop that exits once waiting_for_input becomes False or when
     while waiting_for_input:
         print('Please choose')
         print('1: Add a new transaction value')
         print('2: Mine a new block')
         print('3: Output the blockchain blocks')
         print('4: Check transaction validity')
         print('5: Create wallet')
         print('6: Load wallet')
         print('7: Save keys')
         print('q: Quit')
         user_choice = self.get_user_choice()
         if user_choice == '1':
             tx_data = self.get_transaction_value()
             recipient, amount = tx_data  # tuple unpacking!
             # Add the transaction amount to the blockchain
             signature = self.wallet.sign_transaction(
                 self.wallet.public_key, recipient, amount)
             if self.blockchain.add_transaction(recipient,
                                                self.wallet.public_key,
                                                signature,
                                                amount=amount):
                 print('Added transaction!')
             else:
                 print('Transaction failed!')
             print(self.blockchain.get_open_transactions()
                   )  # testing purpose only!
         elif user_choice == '2':
             if not self.blockchain.mine_block():
                 print('Mining failed. Got no wallet?')
         elif user_choice == '3':
             self.print_blockchain_elements()
         elif user_choice == '4':
             if Verification.verify_transactions(
                     self.blockchain.get_open_transactions(),
                     self.blockchain.get_balance):
                 print('All transactions are valid')
             else:
                 print('There are invalid transactions')
         elif user_choice == '5':
             self.wallet.create_keys()
             self.blockchain = Blockchain(self.wallet.public_key)
         elif user_choice == '6':
             self.wallet.load_keys()
             self.blockchain = Blockchain(self.wallet.public_key)
         elif user_choice == '7':
             self.wallet.save_keys()
         elif user_choice == 'q':
             waiting_for_input = False
         else:
             print('Unknown command. Please, enter choice from the list.')
         if not Verification.verify_chain(self.blockchain.chain):
             self.print_blockchain_elements()
             print('Invalid blockchain!')
             # Break out of the loop
             break
         print('Balance of {}: {:6.2f}'.format(
             self.wallet.public_key, self.blockchain.get_balance()))
     else:
         print('User left!')
     print('Done!')
Пример #18
0
    elif user_choice == '2':
        if mine_block():
            open_transactions = []
            save_data()

    elif user_choice == '3':
        print_blockchain_elements()

    elif user_choice == '4':
        verifier = Verification()
        if verifier.verify_transactions(open_transactions, get_balance):
            print('All transactions are valid.')
        else:
            print('There are invalid transactions.')
    elif user_choice == 'q':
        waiting_for_input = False

    else:
        print('Input was invalid, please pick a value from the list!')

    verifier = Verification()
    if not verifier.verify_chain(blockchain):
        print_blockchain_elements()
        print('Blockchain no longer valid')
        break
    print('Balace of {}: {:6.2f}'.format('John', get_balance('John')))
else:
    print('User left!')

print('Done!')
Пример #19
0
    def resolve_conflicts(self) -> bool:
        """
        This is our Consensus Algorithm. It resolves conflicts by replacing our chain with
        the longest one in the network.

        :return: <bool> True if our chain was replaces, False if not
        """

        logger.debug("Resolving conflicts between the nodes if applicable")

        neighbours = self.nodes
        new_chain = None

        # We're only looking for chains longer than ours
        current_chain_length = len(self.chain)

        # Grab and verify the chains from all the nodes in our network
        for node in neighbours:
            response = requests.get(f"{node}/chain")

            if response.ok:
                length = response.json()["length"]
                chain_hashes = response.json()["chain"]

                chain = []

                for b in chain_hashes:
                    response = requests.get(f"{node}/block/{b}")
                    if response.ok:
                        parsed_block = Block.parse_raw(response.json())
                        chain.append(parsed_block)

                if (length == 1 and current_chain_length == 1
                        and Verification.verify_chain(chain)):
                    logger.debug(
                        "Chain's are both 1 length so preferring neighbour's")
                    current_chain_length = length
                    new_chain = chain

                # Ensure that the chain is sorted by index
                chain.sort(key=lambda x: x.index, reverse=False)

                if length <= current_chain_length:
                    logger.warning("Neighbour's chain shorter than our node")
                    continue

                logger.debug("Neighbour's chain is longer than ours")
                logger.debug("Verifying neighbour's chain")
                if not Verification.verify_chain(chain):
                    logger.warning("Neighbour's chain failed verification")
                    continue

                logger.debug("Neighbour's chain successfully verified")
                current_chain_length = length
                new_chain = chain
                for b in chain:
                    for tx_hash in b.transactions:
                        response = requests.get(
                            f"{node}/transaction/{tx_hash}")
                        if response.ok:
                            t = FinalTransaction.parse_raw(
                                response.json()["transaction"])
                            FinalTransaction.SaveTransaction(
                                self.data_location, t,
                                response.json()["type"])

        # Replace our chain if we discovered a new, valid chain longer than ours
        if new_chain:
            logger.info("Replacing our chain with neighbour's chain")
            self.chain = new_chain
            Block.DeleteBlocks(self.data_location)
        else:
            logger.info("Keeping this node's chain. Now making sure its saved")

        self.save_data()
        return new_chain is not None and len(new_chain) > 0