Exemplo n.º 1
0
class Peer():
    def __init__(self):

        # Define the data and variables that will be used by the Peer
        self.profile = {
            'id': None,
            'username': None,
            'addr': None,
            'port': None,
        }  # This Peer's Info
        self.contacts = ContactList()  # Contact List
        self.blockchain = Blockchain()  # Blockchain
        self.wallet = Wallet()  # Wallet
        self.battery = Wallet(currency='kW')  # Battery Bank
        self.listen_port = 0  # Where to contact this Peer

        self.notifications = []

        self.awaitingValidation = True
        self.validated = False

    def serverGo(self):
        self.server = PeerServer(
            kwargs={
                'contacts': self.contacts,
                'blockchain': self.blockchain,
                'wallet': self.wallet,
                'port': self.listen_port,
                'profile': self.profile,
                'notifications': self.notifications,
            })

    def clientGo(self):
        self.client = PeerClient(
            kwargs={
                'contacts': self.contacts,
                'blockchain': self.blockchain,
                'wallet': self.wallet,
                'port': self.listen_port,
                'profile': self.profile,
                'notifications': self.notifications,
                'awaitFlag': self.awaitingValidation,
                'validatedFlag': self.validated
            })

    def register(self):
        self.client.register("127.0.0.1", 10000)

    def updateContacts(self, contacts):
        self.contacts = contacts

    def getPort(self):
        self.listen_port = self.server.getPort()

    def checkWallet(self):
        return self.wallet.getBalance()

    def checkBattery(self):
        return self.battery.getBalance()

    def startMenu(self):
        try:

            res = ""
            # Clear the screen
            os.system('cls' if os.name == 'nt' else 'clear')

            while True:

                print("1. Contacts")
                print("2. Start Transaction")
                print("3. Check Wallet")
                print("4. Check Battery")
                print("5. Check Blockchain")
                print("6. Notifications", len(self.notifications))
                print("7. Exit\n")
                if res != "":
                    if 'hash' in res:
                        print("*** CURRENT BLOCKCHAIN ***\n")
                        pprint.pprint(res)
                    else:
                        print(res)
                    print()
                choice = input("Select: ")

                print()

                if choice == '1':

                    res = "*** CONTACTS ***\n"
                    res += str(self.contacts.all())

                elif choice == '2':

                    generating_transaction = False
                    while not generating_transaction:
                        # Clear the screen
                        os.system('cls' if os.name == 'nt' else 'clear')

                        print("Transaction Generator")
                        print("1. Buy Energy")
                        print("2. Sell Energy")
                        print("3. Cancel")
                        print()

                        t_choice = input("Select: ")

                        if t_choice == '1':
                            # Clear the screen
                            os.system('cls' if os.name == 'nt' else 'clear')

                            amount = int(
                                input(
                                    "How much energy (kW) do you wish to purchase: "
                                ))
                            transaction = {'type': 'buy', 'amount': amount}
                            if self.startTransaction(transaction):
                                res = 'Transaction Completed'
                            else:
                                res = 'Transaction could not be completed. Try again ...'

                            generating_transaction = True
                        elif t_choice == '2':
                            # Clear the screen
                            os.system('cls' if os.name == 'nt' else 'clear')

                            amount = int(
                                input(
                                    "How much energy (kW) do you wish to sell: "
                                ))
                            transaction = {'type': 'sell', 'amount': amount}
                            if self.startTransaction(transaction):
                                res = 'Transaction Completed'
                            else:
                                res = 'Transaction could not be completed. Try again ...'

                            generating_transaction = True
                        elif t_choice == '3':
                            print("Tansaction Cancelled")
                            generating_transaction = True

                        else:
                            print("Not a valid choice. Try again ...")
                            pass

                elif choice == '3':
                    res = "*** WALLET BALANCE ***\n"
                    res += "Balance\t" + str(self.checkWallet())

                elif choice == '4':
                    res = "*** BATTERY BALANCE ***\n"
                    res += "Balance\t" + str(self.checkBattery())

                elif choice == '5':

                    res = str(self.blockchain.chain)

                elif choice == '6':

                    res = "*** NOTIFICATIONS ***\n"
                    for n in self.notifications:
                        res += str(n) + "\n"

                    self.notifications = []

                elif choice == '7':
                    res = "BYE\n"
                    exit()

                # Clear the screen
                os.system('cls' if os.name == 'nt' else 'clear')

                pass
        except Exception as e:
            print(e)
            exit()

    def startTransaction(self, transaction):
        # check which type of transaction
        if transaction['type'] == 'buy':
            # Check that the Peer has the funding for the purchase
            # NOTE: Hardcoded price
            total_cost = transaction['amount'] * PRICE
            if total_cost > self.wallet.getBalance():
                self.notifications.append(
                    datetime.now().strftime("%H:%M:%S") +
                    "\tInsufficient funds for this purchase")
                return False
            else:
                # Create the block with the new transaction
                self.blockchain.add_transaction(str(self.profile['username']),
                                                'Smart Grid', total_cost,
                                                transaction['amount'])
                self.blockchain.add_block()

                # Propose the block with the new transaction
                self.client.propose()

                # Ensure we do not proceed until validation has been completed
                while self.client.validationStatus():
                    print("Client Awaiting Validation")
                    time.sleep(1)

                if self.client.isValidated():
                    # If all is in order, Carry out the transaction
                    self.wallet.withdrawal(total_cost)
                    self.battery.deposit(transaction['amount'])

                self.validated = False
                self.awaitingValidation = True

            return True
        elif transaction['type'] == 'sell':
            # Check that the Peer has the energy for the transaction
            # NOTE: Hardcoded price
            total_cost = transaction['amount'] * PRICE
            if transaction['amount'] > self.battery.getBalance():
                self.notifications.append(
                    datetime.now().strftime("%H:%M:%S") +
                    "\tInsufficient energy for this transaction")
                return False
            else:
                # Create the block with the new transaction
                self.blockchain.add_transaction(str(self.profile['username']),
                                                'Smart Grid', total_cost,
                                                transaction['amount'])
                self.blockchain.add_block()

                # Propose the block with the new transaction
                self.client.propose()

                # Ensure we do not proceed until validation has been completed
                while self.client.validationStatus():
                    print("Client Awaiting Validation")
                    time.sleep(1)

                if self.client.isValidated():
                    # If all is in order, Carry out the transaction
                    self.wallet.deposit(total_cost)
                    self.battery.withdrawal(transaction['amount'])

                self.validated = False
                self.awaitingValidation = True

            return True
        else:
            return False