示例#1
0
    def send_transaction_to_clients_if_needed(self, transaction: Transaction):
        for username in list(self.dict_of_clients_and_usernames.keys()):
            if transaction.sender_username == username or transaction.receiver_username == username:
                if not self.server_database.users_table.is_user_exist(
                        transaction.sender_username) or not self.server_database.users_table.is_user_exist(
                    transaction.receiver_username):
                    return  # one of the users does not exist so so nothing
                sender = self.server_database.users_table.get_user(transaction.sender_username)
                receiver = self.server_database.users_table.get_user(transaction.receiver_username)

                if sender.balance - transaction.amount < 0:
                    print('not enough money')
                    return  # aka not enough money

                if transaction.is_signature_valid(sender.pk, receiver.pk):  # both valid
                    msg = MessageBetweenNodeAndClient(MessageType.TRANSACTION_COMPLETED,
                                                      transaction.as_str())
                elif transaction.receiver_username == username and transaction.is_sender_signature_valid(sender.pk):
                    msg = MessageBetweenNodeAndClient(MessageType.TRANSACTION_OFFERED,
                                                      transaction.as_str())
                else:
                    continue

                try:
                    msg.send(self.dict_of_clients_and_usernames[username])
                except ConnectionError:
                    self.dict_of_clients_and_usernames.pop(username)
示例#2
0
    def send_coins(self):
        """
        called when user pressed send in the send coins screen
        :return:

        """
        receiver_username = self.root.ids.SendScreen.ids.receiver_username_wig.text
        amount = self.root.ids.SendScreen.ids.amount_wig.text
        description = self.root.ids.SendScreen.ids.description_wig.text

        self.root.ids.SendScreen.ids.receiver_username_wig.text = ''
        self.root.ids.SendScreen.ids.amount_wig.text = ''
        self.root.ids.SendScreen.ids.description_wig.text = ''

        if check_if_input_is_empty(receiver_username, amount):
            PopUp_Invalid_input('fiil out username and amount ')
            return
        try:
            amount = float(amount)
        except ValueError:
            PopUp_Invalid_input('amount should be a a valid number')
            return

        if not amount > 0:
            PopUp_Invalid_input('amount should be positive')
            return

        if self.current_user.balance < amount:
            PopUp_Invalid_input('not enough money')
            return

        if self.current_user.username == receiver_username:
            PopUp_Invalid_input('cannot send money to yourself')
            return
        transaction = Transaction(self.current_user.username, receiver_username, amount, description)
        signature = self.current_user.private_key.sign(transaction.data_as_str())
        transaction.sender_signature = signature

        try:
            msg = MessageBetweenNodeAndClient(MessageType.TRANSACTION_OFFERED, transaction.as_str())
            msg.send(self.my_socket)
        except ConnectionError:
            self.back_to_menu()
            PopUp_Invalid_input('server dissconnected')
            return
        self.root.current = "UserPageScreen"
示例#3
0
 def add_declined_transaction(self, username: str,
                              transaction: Transaction):
     lodt = self.get_list_of_declined_transactions(username)
     lodt.append(transaction.as_str())
     lodt_as_str = json.dumps(lodt)
     command = f'''UPDATE Users  SET LODT = '{lodt_as_str}' WHERE Username = '******';'''
     self.__cursor.execute(command)
     self.__connection.commit()
示例#4
0
 def process_transaction(self, transaction: Transaction, type: MessageType, change_balance=True):
     print(f'processing {transaction.as_str()}')
     print(f'reciver {transaction.receiver_username}')
     print(f'giver {transaction.sender_username}')
     if type == MessageType.TRANSACTION_COMPLETED:
         print('tran complete')
         if change_balance:
             self.update_balance(transaction=transaction)
         self.list_of_completed_transactions.append(transaction)
         if transaction.__str__() in self.dict_of_repr_to_offered_transactions.keys():
             self.dict_of_repr_to_offered_transactions.pop(transaction.__str__())
         self.root.ids.UserPageScreen.ids.RecantsTransactions.update_grid(self.list_of_completed_transactions)
         self.root.ids.ReceiveScreen.ids.OfferedTransactions.update_grid(
             self.dict_of_repr_to_offered_transactions.values(), self.move_to_receive_full_screen)
     elif type == MessageType.TRANSACTION_OFFERED:
         if transaction.as_str() in self.wallet_database.get_list_of_declined_transactions(
                 self.current_user.username):
             return
         self.dict_of_repr_to_offered_transactions[transaction.__str__()] = transaction
         self.root.ids.ReceiveScreen.ids.OfferedTransactions.update_grid(
             self.dict_of_repr_to_offered_transactions.values(), self.move_to_receive_full_screen)
     else:
         raise Exception(f'unxepect msg {type.name}')
示例#5
0
    def recv_msg_from_server(self, *args):
        self.acquire()
        if self.root.current in ["UserPageScreen", "SendScreen", "FullReceiveScreen",
                                 "ReceiveScreen"]:  # TODO add all needed screens
            try:
                msg = MessageBetweenNodeAndClient()
                msg.recv(self.my_socket)
                if msg.message_type == MessageType.RECEIVE_ALL_TRANSACTIONS:
                    list_of_transactions, current_amount_of_money = json.loads(msg.content)
                    print(float(current_amount_of_money), "current_amount_of_money")
                    list_of_transactions = [
                        (Transaction.create_from_str(tup[0]), MessageType(int(tup[1]))) for tup in
                        list_of_transactions]
                    for tup in list_of_transactions:
                        self.process_transaction(tup[0], tup[1], change_balance=False)  # (transaction,msg_type)
                    self.update_balance(amount=float(current_amount_of_money))
                elif msg.message_type in [MessageType.TRANSACTION_OFFERED,
                                          MessageType.TRANSACTION_COMPLETED]:
                    tran = Transaction.create_from_str(msg.content)
                    self.process_transaction(tran, msg.message_type)
                    Pop_notifications(Notification.create(msg.message_type), transaction_text=tran.__str__())
                elif msg.message_type == MessageType.BLOCK_UPLOADED:
                    amount = float(msg.content)
                    self.update_balance(amount=amount)



            except socket.timeout:
                self.release()
                return
            except ConnectionError:
                PopUp_Invalid_input('server dissconected')
                self.root.current = "MenuScreen"
                self.close_socket()
                self.current_user.clear()

        self.release()
示例#6
0
    def create_block_from_tuple(tup: tuple):
        id, parent_id, sequence_number, level, security_number, uploader_username, last_block_hash, current_block_hash, proof_of_work, timestamp, list_of_transactions, list_of_new_users = tup
        list_of_new_users_as_str = json.loads(list_of_new_users)
        list_of_transactions_as_str = json.loads(list_of_transactions)
        list_of_new_users = []
        list_of_transactions = []

        for i in list_of_new_users_as_str:
            list_of_new_users.append(User.create_from_str(i))

        for i in list_of_transactions_as_str:
            t = Transaction.create_from_str(i)
            list_of_transactions.append(t)
        b = Block(uploader_username, list_of_transactions, list_of_new_users,
                  last_block_hash, timestamp, current_block_hash)
        b.set_table_parameters(id, parent_id, sequence_number, level,
                               security_number)
        b.proof_of_work = proof_of_work
        return b
示例#7
0
 def create_block_from_tuple_received(tup):
     uploader_username, timestamp, list_of_transactions_as_str, list_of_new_users_as_str, pow, last_block_hash = tup
     list_of_new_users_as_str = json.loads(list_of_new_users_as_str)
     list_of_transactions_as_str = json.loads(list_of_transactions_as_str)
     list_of_new_users = [
         User.create_from_str(user_as_str)
         for user_as_str in list_of_new_users_as_str
     ]
     list_of_transactions = [
         Transaction.create_from_str(block_as_str)
         for block_as_str in list_of_transactions_as_str
     ]
     b = Block(uploader_username,
               list_of_transactions,
               list_of_new_users,
               last_block_hash,
               timestamp=timestamp)
     b.proof_of_work = pow
     return b
    def get_all_transactions_of(self, username: str):
        if not self.users_table.is_user_exist(username):
            return [], -1

        command = f'''SELECT LOT FROM Blockchain WHERE SecurityNumber > {self.blockchain_table.calculate_security_number_threshold()}'''
        list_to_send = []
        self.blockchain_table.cursor.execute(command)
        list_of_list_of_transactions = self.blockchain_table.cursor.fetchall()
        for tup in list_of_list_of_transactions:
            list_of_transactions = json.loads(tup[0])
            for transaction in list_of_transactions:
                transaction = Transaction.create_from_str(transaction)
                if transaction.sender_username == username or transaction.receiver_username == username:
                    if not self.users_table.is_user_exist(
                            transaction.sender_username
                    ) or not self.users_table.is_user_exist(
                            transaction.receiver_username):
                        continue  # one of the users does not exist so so nothing
                    sender = self.users_table.get_user(
                        transaction.sender_username)
                    receiver = self.users_table.get_user(
                        transaction.receiver_username)

                    if transaction.is_signature_valid(
                            sender.pk, receiver.pk):  # both valid
                        list_to_send.append((
                            transaction,
                            MessageType.TRANSACTION_COMPLETED.value.__str__()))
                    elif transaction.receiver_username == username and transaction.is_sender_signature_valid(
                            sender.pk):
                        list_to_send.append(
                            (transaction,
                             MessageType.TRANSACTION_OFFERED.value.__str__()))

        current_amount_of_money = float(self.users_table.get_balance(username))

        return list_to_send, current_amount_of_money
示例#9
0
    def handle_client(self, client_socket: socket):
        username = ''
        client_socket.settimeout(0.2)
        client_state = ClientState.NOT_LOGGED_IN
        try:
            while True:
                try:
                    self.acquire()
                    if client_state == ClientState.NOT_LOGGED_IN:
                        msg = MessageBetweenNodeAndClient()
                        client_socket.settimeout(SOCKET_CLIENT_RECEIVE_SHORT_TIMEOUT)
                        t = time.time()
                        msg.recv(client_socket)

                        client_socket.settimeout(SOCKET_CLIENT_RECEIVE_LONG_TIMEOUT)
                        if msg.message_type == MessageType.SIGN_UP:
                            list_of_data = json.loads(msg.content)
                            username, pk_as_str = list_of_data
                            pk = Key.create_from_str(pk_as_str)
                            # check if pk and username are taken and send result to client {
                            is_user_taken = self.server_database.users_table.is_user_exist(username)
                            is_pk_taken = self.server_database.users_table.is_public_key_exist(pk)
                            content = str(int(is_user_taken)) + str(int(is_pk_taken))
                            msg_to_send = MessageBetweenNodeAndClient(MessageType.SIGN_UP_ANSWER,
                                                                      content)
                            msg_to_send.send(client_socket)
                            # }

                            if not is_user_taken and not is_pk_taken:
                                pass  # add user to upload
                                user = User(username, pk)
                                self.list_of_new_users_to_upload.append(user)
                                self.dict_of_clients_and_usernames_waiting_for_confirmation[user] = client_socket
                                client_state = ClientState.WAITING_FOR_CONFIRMATION
                            else:
                                pass
                        elif msg.message_type == MessageType.LOG_IN_REQUEST:
                            username = msg.content
                            if not self.server_database.users_table.is_user_exist(username):
                                print(f'not user named {username}')
                                msg = MessageBetweenNodeAndClient(MessageType.LOG_IN_FAILED)
                                msg.send(client_socket)

                            random = str(randint(0, 10000))
                            msg = MessageBetweenNodeAndClient(MessageType.LOG_IN_RAND, random)
                            msg.send(client_socket)

                            msg.recv(client_socket)
                            if msg.message_type != MessageType.LOG_IN_RAND_ANSWER:
                                raise Exception('unxpexted msg')
                            client_pk = self.server_database.users_table.get_public_key(username)
                            if not client_pk.verify(msg.content, random):
                                msg = MessageBetweenNodeAndClient(MessageType.LOG_IN_FAILED)
                            else:
                                msg = MessageBetweenNodeAndClient(MessageType.LOG_IN_ACCEPTED)
                            msg.send(client_socket)
                            client_socket.settimeout(SOCKET_CLIENT_RECEIVE_SHORT_TIMEOUT)
                            self.dict_of_clients_and_usernames[username] = client_socket
                            client_state = ClientState.LOGGED_IN
                        else:
                            raise Exception('unxpexted msg')

                    elif client_state == ClientState.LOGGED_IN:
                        msg = MessageBetweenNodeAndClient()
                        msg.recv(client_socket)
                        if msg.message_type == MessageType.GET_ALL_TRANSACTIONS:
                            # serch the database for all transactions revolving the user {
                            tuples, current_amount_of_money = self.server_database.get_all_transactions_of(username)
                            print(f'current_amount_of_money {current_amount_of_money} (190)')
                            content = json.dumps(
                                [[(t[0].as_str(), t[1]) for t in tuples], str(current_amount_of_money)])
                            msg_to_send = MessageBetweenNodeAndClient(
                                MessageType.RECEIVE_ALL_TRANSACTIONS, content)
                            msg_to_send.send(client_socket)
                            # }
                        elif msg.message_type == MessageType.TRANSACTION_OFFERED:
                            transaction = Transaction.create_from_str(msg.content)
                            self.list_of_transactions_to_make.append(transaction)
                        elif msg.message_type == MessageType.TRANSACTION_COMPLETED:
                            transaction = Transaction.create_from_str(msg.content)
                            self.list_of_transactions_to_make.append(transaction)
                    elif client_state == ClientState.WAITING_FOR_CONFIRMATION:
                        if self.dict_of_clients_and_usernames_waiting_for_confirmation.get(user) is None:
                            client_socket.close()
                            self.release()
                            return

                    self.release()
                except socket.timeout:
                    self.release()


        except ConnectionError or json.decoder.JSONDecodeError as e:
            print(e)
            print('nlafsdfdsfdsfds')
            self.release()
            return
        def make_transaction(self, transaction: Transaction, node):

            if not self.is_user_exist(
                    transaction.receiver_username
            ) or not self.is_user_exist(
                    transaction.sender_username
            ) or transaction.receiver_username == transaction.sender_username:
                return  # one of the user does not exist or the receiver_username is also  sender_username

            sender = self.get_user(transaction.sender_username)
            receiver = self.get_user(transaction.receiver_username)

            print(
                f'sender: {sender.username} , {sender.pk.as_str()}, {sender.balance}'
            )
            print(
                f'receiver: {receiver.username} , {receiver.pk.as_str()}, {receiver.balance}'
            )

            if sender.balance - transaction.amount < 0:
                print('not enough money')
                return  # aka not enough money

            # TODO: check digital signature of both users{
            sender_pk = sender.pk
            receiver_pk = receiver.pk

            is_tran_valid = transaction.is_signature_valid(
                sender_pk, receiver_pk)
            print(f'is_tran_valid {is_tran_valid}')
            #  }

            # changing the users balance{
            if is_tran_valid:
                self.update_balance(sender.username,
                                    sender.balance - transaction.amount)
                self.update_balance(receiver.username,
                                    receiver.balance + transaction.amount)

            for username in list(node.dict_of_clients_and_usernames.keys()):
                if transaction.sender_username == username or transaction.receiver_username == username:
                    if not self.is_user_exist(
                            transaction.sender_username
                    ) or not self.is_user_exist(transaction.receiver_username):
                        return  # one of the users does not exist so so nothing
                    if transaction.is_signature_valid(
                            sender.pk, receiver.pk):  # both valid
                        msg = MessageBetweenNodeAndClient(
                            MessageType.TRANSACTION_COMPLETED,
                            transaction.as_str())
                    elif transaction.receiver_username == username and transaction.is_sender_signature_valid(
                            sender.pk):
                        print("transaction.receiver_signature",
                              transaction.receiver_signature)
                        msg = MessageBetweenNodeAndClient(
                            MessageType.TRANSACTION_OFFERED,
                            transaction.as_str())
                    else:
                        continue
                    try:
                        msg.send(node.dict_of_clients_and_usernames[username])
                    except ConnectionError:
                        node.dict_of_clients_and_usernames.pop(username)