Esempio n. 1
0
 def closeEvent(self, *args, **kwargs):
     sys.stdout = sys.__stdout__
     sys.stderr = sys.__stderr__
     # Terminate the running threads.
     # Set the shutdown flag on each thread to trigger a clean shutdown of each thread.
     self.mainWindow.myRpcWd.shutdown_flag.set()
     print("Saving stuff & closing...")
     if getattr(self.mainWindow.hwdevice, 'dongle', None) is not None:
         self.mainWindow.hwdevice.dongle.close()
         print("Dongle closed")
         
     # Save window/splitter size to cache file
     self.cache["window_width"] = self.width()
     self.cache["window_height"] = self.height()
     self.cache["splitter_sizes"] = self.mainWindow.splitter.sizes()
     self.cache["console_hidden"] = (self.mainWindow.btn_consoleToggle.text() == 'Show')
     
     # Save mnList order to cache file
     mnOrder = {}
     mnList = self.mainWindow.tabMain.myList
     for i in range(mnList.count()):
         mnName = mnList.itemWidget(mnList.item(i)).alias
         mnOrder[mnName] = i
     self.cache['mnList_order'] = mnOrder
     
     # Write cache file
     writeToFile(self.cache, cache_File)
     print("Bye Bye.")
     return QMainWindow.closeEvent(self, *args, **kwargs)
Esempio n. 2
0
    def onRemoveMN(self, data=None):
        if not data:
            target = self.ui.sender()
            masternode_alias = target.alias

            reply = self.caller.myPopUp(
                QMessageBox.Warning, 'Confirm REMOVE',
                "Are you sure you want to remove\nmasternoode:'%s'" %
                masternode_alias, QMessageBox.No)

            if reply == QMessageBox.No:
                return

            for masternode in self.caller.masternode_list:
                if masternode['name'] == masternode_alias:
                    self.caller.masternode_list.remove(masternode)
                    break
            try:
                writeToFile(self.caller.masternode_list, masternodes_File)
                self.ui.myList.takeItem(
                    self.ui.myList.row(self.ui.current_mn[masternode_alias]))
            except Exception as e:
                err_msg = "Error writing masternode file"
                printException(getCallerName(), getFunctionName(), err_msg, e)

            # Clear voting masternodes configuration and update cache
            self.caller.t_governance.clear()
Esempio n. 3
0
    def onButtonSave(self, main_dlg):
        main_dlg.rpc_ip = ip_address(self.edt_rpcIp.text().strip()).compressed
        main_dlg.rpc_port = int(self.edt_rpcPort.value())
        main_dlg.rpc_user = self.edt_rpcUser.text()
        main_dlg.rpc_password = self.edt_rpcPassword.text()
        conf = {}
        conf["rpc_ip"] = main_dlg.rpc_ip
        conf["rpc_port"] = main_dlg.rpc_port
        conf["rpc_user"] = main_dlg.rpc_user
        conf["rpc_password"] = main_dlg.rpc_password

        urlstring = "http://%s:%s@%s:%d" % (conf["rpc_user"],
                                            conf["rpc_password"],
                                            conf["rpc_ip"], conf["rpc_port"])

        if checkRPCstring(urlstring,
                          action_msg="Restoring previous configuration"):
            # Update datafile
            writeToFile(conf, rpc_File)
            # Update current RPC Server
            main_dlg.main_wnd.mainWindow.rpcClient = None
            main_dlg.main_wnd.mainWindow.rpcConnected = False
            printDbg("Trying to connect to RPC server [%s]:%s" %
                     (conf["rpc_ip"], str(conf["rpc_port"])))
            self.runInThread = ThreadFuns.runInThread(
                main_dlg.main_wnd.mainWindow.updateRPCstatus, (),
                main_dlg.main_wnd.mainWindow.updateRPCled)
        else:
            printDbg("Restored RPC credentials. ")

        main_dlg.close()
    def onButtonSave(self, main_dlg):
        try:
            main_dlg.rpc_ip = ip_address(
                self.edt_rpcIp.text().strip()).compressed
            main_dlg.rpc_port = int(self.edt_rpcPort.value())
            main_dlg.rpc_user = self.edt_rpcUser.text()
            main_dlg.rpc_password = self.edt_rpcPassword.text()
            conf = {}
            conf["rpc_ip"] = main_dlg.rpc_ip
            conf["rpc_port"] = main_dlg.rpc_port
            conf["rpc_user"] = main_dlg.rpc_user
            conf["rpc_password"] = main_dlg.rpc_password

            # Update File
            writeToFile(conf, rpc_File)

            # Update current RPC Server
            main_dlg.main_wnd.mainWindow.rpcClient = None
            main_dlg.main_wnd.mainWindow.rpcConnected = False
            printDbg("Trying to connect to RPC server [%s]:%s" %
                     (conf["rpc_ip"], str(conf["rpc_port"])))
            self.runInThread = ThreadFuns.runInThread(
                main_dlg.main_wnd.mainWindow.updateRPCstatus, (),
                main_dlg.main_wnd.mainWindow.updateRPCled)
            main_dlg.close()

        except Exception as e:
            print(e)
Esempio n. 5
0
    def onButtonSend(self):
        try:
            self.dest_addr = self.ui.edt_destination.text().strip()
            if self.useSwiftX():
                self.currFee = 0.01 * 1e8
            else:
                self.currFee = self.ui.feeLine.value() * 1e8
             
             # Check RPC & dongle  
            if not self.main_tab.caller.rpcConnected or self.main_tab.caller.hwStatus != 2:
                self.main_tab.caller.myPopUp2(QMessageBox.Critical, 'SPMT - hw/rpc device check', "Connect to RPC server and HW device first")
                return None
            
            # Check destination Address      
            if not checkPivxAddr(self.dest_addr):
                self.main_tab.caller.myPopUp2(QMessageBox.Critical, 'SPMT - PIVX address check', "The destination address is missing, or invalid.")
                return None

            # LET'S GO
            if len(self.rawtransactions) > 0:
                printDbg("Preparing transaction. Please wait...")
                self.ui.loadingLine.show()
                self.ui.loadingLinePercent.show()
                QApplication.processEvents()
                
                # save last destination address and swiftxCheck to cache
                self.main_tab.caller.parent.cache["lastAddress"] = self.dest_addr
                self.main_tab.caller.parent.cache["useSwiftX"] = self.useSwiftX()
                writeToFile(self.main_tab.caller.parent.cache, cache_File)
                    
                # re-connect signals
                try:
                    self.main_tab.caller.hwdevice.sigTxdone.disconnect()
                except:
                    pass
                try:
                    self.main_tab.caller.hwdevice.sigTxabort.disconnect()
                except:
                    pass
                try:
                    self.main_tab.caller.hwdevice.tx_progress.disconnect()
                except:
                    pass
                self.main_tab.caller.hwdevice.sigTxdone.connect(self.FinishSend)
                self.main_tab.caller.hwdevice.sigTxabort.connect(self.AbortSend)
                self.main_tab.caller.hwdevice.tx_progress.connect(self.updateProgressPercent)
    
                self.txFinished = False
                self.main_tab.caller.hwdevice.prepare_transfer_tx_bulk(self.main_tab.caller, self.rewards, self.dest_addr, self.currFee, self.rawtransactions, self.useSwiftX())
            else:
                self.main_tab.caller.myPopUp2(QMessageBox.Information, 'Transaction NOT sent', "No UTXO to send") 
                
        except DisconnectedException as e:
            self.main_tab.caller.hwStatus = 0
            self.main_tab.caller.updateHWleds()
            self.onButtonCancel()
                
        except Exception as e:
            err_msg = "Exception in onButtonSend"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
Esempio n. 6
0
 def onOK(self):
     self.main_wnd.votingMasternodes = self.getSelection()
     self.main_wnd.updateSelectedMNlabel()
     # save voting masternodes to cache
     self.main_wnd.caller.parent.cache[
         'votingMasternodes'] = self.main_wnd.votingMasternodes
     writeToFile(self.main_wnd.caller.parent.cache, cache_File)
     self.accept()
Esempio n. 7
0
    def loadMNConf(self, fileName):
        hot_masternodes = loadMNConfFile(fileName)
        if hot_masternodes == None:
            messText = "Unable to load data from file '%s'" % fileName
            self.myPopUp2(QMessageBox.Warning, "SPMT - warning", messText)
        else:
            # Append new masternodes to list
            new_masternodes = []
            skip_masternodes = []
            for x in hot_masternodes:
                if not self.isMasternodeInList(x['name']):
                    self.masternode_list.append(x)
                    new_masternodes.append(x)
                else:
                    skip_masternodes.append(x)

            # Show new list
            for new_masternode in new_masternodes:
                name = new_masternode['name']
                self.tabMain.insert_mn_list(name,
                                            new_masternode['ip'],
                                            new_masternode['port'],
                                            None,
                                            isHardware=False)
                self.tabMain.btn_remove[name].clicked.connect(
                    lambda: self.t_main.onRemoveMN())

            # print number of nodes added
            new_nodes = len(new_masternodes)
            final_message = ""
            if new_nodes == 0:
                final_message = "No External Masternode "
            elif new_nodes == 1:
                final_message = "1 External Masternode "
            else:
                final_message = "%d External Masternodes " % new_nodes
            final_message += "added to the list. "
            if new_nodes > 0:
                final_message += str([x['name']
                                      for x in new_masternodes]) + ".  "
            if len(skip_masternodes) > 0:
                final_message += "Following entries skipped due to duplicate names:"
                final_message += str([x['name']
                                      for x in skip_masternodes]) + ".  "
            printDbg(final_message)

            if new_nodes > 0:
                # update files
                printDbg("saving MN configuration file")
                writeToFile(self.masternode_list, masternodes_File)
                printDbg("saved")
                # Clear voting masternodes configuration and update cache
                self.t_governance.clear()
Esempio n. 8
0
    def onButtonSend(self):
        try:
            self.dest_addr = self.ui.edt_destination.text().strip()
            self.currFee = self.ui.feeLine.value() * 1e8

            # Check RPC & dongle
            if not self.main_tab.caller.rpcConnected or self.main_tab.caller.hwStatus != 2:
                self.main_tab.caller.myPopUp2(
                    QMessageBox.Critical, 'SPMT - hw/rpc device check',
                    "Connect to RPC server and HW device first")
                return None

            # Check destination Address
            if not checkPivxAddr(self.dest_addr):
                self.main_tab.caller.myPopUp2(
                    QMessageBox.Critical, 'SPMT - PIVX address check',
                    "The destination address is missing, or invalid.")
                return None

            printDbg("Preparing transaction. Please wait...")
            self.ui.loadingLine.show()
            self.main_tab.caller.parent.app.processEvents()
            # save destination address to cache
            if self.dest_addr != self.main_tab.caller.parent.cache.get(
                    "lastAddress"):
                self.main_tab.caller.parent.cache[
                    "lastAddress"] = self.dest_addr
                writeToFile(self.main_tab.caller.parent.cache, cache_File)

            # re-connect signals
            try:
                self.main_tab.caller.hwdevice.sigTxdone.disconnect()
                self.main_tab.caller.hwdevice.sigTxabort.disconnect()
            except:
                pass
            self.main_tab.caller.hwdevice.sigTxdone.connect(self.FinishSend)
            self.main_tab.caller.hwdevice.sigTxabort.connect(self.AbortSend)

            self.txFinished = False
            self.main_tab.caller.hwdevice.prepare_transfer_tx_bulk(
                self.main_tab.caller, self.rewards, self.dest_addr,
                self.currFee, self.rawtransactions)

        except Exception as e:
            err_msg = "Exception in SendRewards"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
Esempio n. 9
0
    def vote_thread(self, ctrl, vote_code):
        if not isinstance(vote_code, int) or vote_code not in range(3):
            raise Exception("Wrong vote_code %s" % str(vote_code))

        # Uncomment when needed
        # self.successVotes = 0
        # self.failedVotes = 0

        # save delay check data to cache
        self.caller.parent.cache[
            "votingDelayCheck"] = self.ui.randomDelayCheck.isChecked()
        self.caller.parent.cache[
            "votingDelayNeg"] = self.ui.randomDelayNeg_edt.value()
        self.caller.parent.cache[
            "votingDelayPos"] = self.ui.randomDelayPos_edt.value()
        writeToFile(self.caller.parent.cache, cache_File)

        server_url = "http://{}:{}".format(self.caller.rpcClient.rpc_ip,
                                           self.caller.rpcClient.rpc_port)
        auth_pair = self.caller.rpcClient.rpc_user, self.caller.rpcClient.rpc_passwd

        for prop, mn in product(self.selectedTorrents, self.votingMasternodes):
            try:
                v_res = requests.post(url=server_url,
                                      auth=auth_pair,
                                      data=self.prepare_vote_data(
                                          prop.Hash, mn[1],
                                          ["ABSTAIN", "yes", "no"][vote_code]))

                response = json.loads(v_res.content)
                if 'error' in response:
                    self.display_error(response['error']['message'])
                    continue
            except Exception as e:
                printException(
                    getCallerName(), getFunctionName(),
                    'Submitting a vote failed', e.args +
                    (prop.Hash, mn[1], ["ABSTAIN", "yes", "no"][vote_code]))
                continue

            if self.ui.randomDelayCheck.isChecked():
                time.sleep(
                    random.randint(-int(self.ui.randomDelayNeg_edt.value()),
                                   int(self.ui.randomDelayPos_edt.value())))
Esempio n. 10
0
    def onSaveMNConf(self):
        try:
            if self.ui.edt_pubKey.text() == "" or self.ui.edt_txid.text(
            ) == "" or self.ui.edt_mnPrivKey.text() == "":
                mess_text = 'Attention! Complete the form before saving.<br>'
                mess_text += "<b>pubKey = </b>%s<br>" % self.ui.edt_pubKey.text(
                )
                mess_text += "<b>txId = </b>%s<br>" % self.ui.edt_txid.text()
                mess_text += "<b>mnPrivKey = </b>%s<br>" % self.ui.edt_mnPrivKey.text(
                )
                self.caller.myPopUp2(QMessageBox.Critical, 'Complete Form',
                                     mess_text)
                return

            if not is_hex(self.ui.edt_txid.text()):
                mess_text = 'Attention! txid format is not valid.<br>'
                mess_text += "<b>txId = </b>%s<br>" % self.ui.edt_txid.text()
                mess_text += 'transaction id must be in hex format.<br>'
                self.caller.myPopUp2(QMessageBox.Critical, 'Complete Form',
                                     mess_text)
                return

            # check for duplicate name
            mn_alias = self.ui.edt_name.text().strip()
            # if we are changing a masternode don't check old alias
            old_alias = None
            if not self.caller.mnode_to_change is None:
                old_alias = self.caller.mnode_to_change['name']
            if self.caller.isMasternodeInList(
                    mn_alias) and old_alias != mn_alias:
                mess_text = 'Attention! The name <b>%s</b> is already in use for another masternode.<br>' % mn_alias
                mess_text += 'Choose a different name (alias) for the masternode'
                self.caller.myPopUp2(QMessageBox.Critical, 'Complete Form',
                                     mess_text)
                return

            # remove previous element
            if not self.caller.mnode_to_change is None:
                # remove from memory list
                self.caller.masternode_list.remove(self.caller.mnode_to_change)
                # remove from tabMain list
                row = self.caller.tabMain.myList.row
                name = self.caller.tabMain.current_mn[
                    self.caller.mnode_to_change['name']]
                self.caller.tabMain.myList.takeItem(row(name))
                self.caller.mnode_to_change = None

            # create new item
            new_masternode = {}
            new_masternode['name'] = mn_alias
            masternodeIp = self.ui.edt_masternodeIp.text().strip()
            if not masternodeIp.endswith('.onion'):
                masternodeIp = ip_address(masternodeIp).compressed
            new_masternode['ip'] = masternodeIp
            new_masternode['port'] = self.ui.edt_masternodePort.value()
            new_masternode['mnPrivKey'] = self.ui.edt_mnPrivKey.text().strip()
            new_masternode['isTestnet'] = 0 if not self.isTestnet() else 1
            new_masternode['isHardware'] = True
            new_masternode['hwAcc'] = self.ui.edt_hwAccount.value()

            coll = {}
            coll['address'] = self.ui.edt_address.text().strip()
            coll['spath'] = self.ui.edt_spath.value()
            coll['pubKey'] = self.ui.edt_pubKey.text().strip()
            coll['txid'] = self.ui.edt_txid.text().strip()
            coll['txidn'] = self.ui.edt_txidn.value()

            new_masternode['collateral'] = coll

            # add new item
            self.caller.masternode_list.append(new_masternode)
            # Write to file
            printDbg("saving MN configuration for %s" % new_masternode['name'])
            writeToFile(self.caller.masternode_list, masternodes_File)
            printDbg("saved")

            # Insert item in list of Main tab and connect buttons
            name = new_masternode['name']
            namelist = [x['name'] for x in self.caller.masternode_list]
            row = namelist.index(name)
            if row == -1:
                row = None
            self.caller.tabMain.insert_mn_list(name, new_masternode['ip'],
                                               new_masternode['port'], row)
            self.caller.tabMain.btn_remove[name].clicked.connect(
                lambda: self.caller.t_main.onRemoveMN())
            self.caller.tabMain.btn_edit[name].clicked.connect(
                lambda: self.caller.t_main.onEditMN())
            self.caller.tabMain.btn_start[name].clicked.connect(
                lambda: self.caller.t_main.onStartMN())
            self.caller.tabMain.btn_rewards[name].clicked.connect(
                lambda: self.caller.t_main.onRewardsMN())

            # Clear voting masternodes configuration and update cache
            self.caller.t_governance.clear()

            # go back
            self.onCancelMNConfig()

        except Exception as e:
            error_msg = "ERROR: %s" % e
            printDbg(error_msg)
            self.caller.myPopUp2(QMessageBox.Critical, 'ERROR', error_msg)
Esempio n. 11
0
 def clear(self):
     # Clear voting masternodes configuration and update cache
     self.votingMasternodes = []
     self.caller.parent.cache['votingMasternodes'] = []
     writeToFile(self.caller.parent.cache, cache_File)
Esempio n. 12
0
    def vote_thread(self, ctrl, vote_code):
        # vote_code index for ["yes", "abstain", "no"]
        if not isinstance(vote_code, int) or vote_code not in range(3):
            raise Exception("Wrong vote_code %s" % str(vote_code))
        self.successVotes = 0
        self.failedVotes = 0

        # save delay check data to cache
        self.caller.parent.cache[
            "votingDelayCheck"] = self.ui.randomDelayCheck.isChecked()
        self.caller.parent.cache[
            "votingDelayNeg"] = self.ui.randomDelayNeg_edt.value()
        self.caller.parent.cache[
            "votingDelayPos"] = self.ui.randomDelayPos_edt.value()
        writeToFile(self.caller.parent.cache, cache_File)

        for prop in self.selectedProposals:
            for mn in self.votingMasternodes:
                vote_sig = ''
                serialize_for_sig = ''
                sig_time = int(time.time())

                try:
                    # Get mnPrivKey
                    currNode = next(x for x in self.caller.masternode_list
                                    if x['name'] == mn[1])
                    if currNode is None:
                        raise Exception(
                            "currNode not found for current voting masternode %s"
                            % mn[1])
                    mnPrivKey = currNode['mnPrivKey']

                    # Add random delay offset
                    if self.ui.randomDelayCheck.isChecked():
                        minuns_max = int(self.ui.randomDelayNeg_edt.value())
                        plus_max = int(self.ui.randomDelayPos_edt.value())
                        delay_secs = random.randint(-minuns_max, plus_max)
                        sig_time += delay_secs

                    # Print Debug line to console
                    mess = "Processing '%s' vote on behalf of masternode [%s]" % (
                        self.vote_codes[vote_code], mn[1])
                    mess += " for the proposal {%s}" % prop.name
                    if self.ui.randomDelayCheck.isChecked():
                        mess += " with offset of %d seconds" % delay_secs
                    printDbg(mess)

                    # Serialize vote
                    serialize_for_sig = mn[0][:64] + '-' + str(
                        currNode['collateral'].get('txidn'))
                    serialize_for_sig += prop.Hash + str(vote_code) + str(
                        sig_time)

                    # Sign vote
                    vote_sig = ecdsa_sign(serialize_for_sig, mnPrivKey)

                    # Broadcast the vote
                    v_res = self.caller.rpcClient.mnBudgetRawVote(
                        mn_tx_hash=currNode['collateral'].get('txid'),
                        mn_tx_index=int(currNode['collateral'].get('txidn')),
                        proposal_hash=prop.Hash,
                        vote=self.vote_codes[vote_code],
                        time=sig_time,
                        vote_sig=vote_sig)

                    printOK(v_res)

                    if v_res == 'Voted successfully':
                        self.successVotes += 1
                    else:
                        self.failedVotes += 1

                except Exception as e:
                    err_msg = "Exception in vote_thread - check MN privKey"
                    printException(getCallerName(), getFunctionName(), err_msg,
                                   e.args)
Esempio n. 13
0
    def onSaveMNConf(self):
        try:
            if self.ui.edt_pubKey.text() == "" or self.ui.edt_txid.text(
            ) == "" or self.ui.edt_mnPrivKey.text() == "":
                mess_text = 'Attention! Complete the form before saving.<br>'
                mess_text += "<b>pubKey = </b>%s<br>" % self.ui.edt_pubKey.text(
                )
                mess_text += "<b>txId = </b>%s<br>" % self.ui.edt_txid.text()
                mess_text += "<b>mnPrivKey = </b>%s<br>" % self.ui.edt_mnPrivKey.text(
                )
                self.caller.myPopUp2(QMessageBox.Critical, 'Complete Form',
                                     mess_text)
                return
            # remove previous element
            if not self.caller.mnode_to_change is None:
                # remove from memory list
                self.caller.masternode_list.remove(self.caller.mnode_to_change)
                # remove from tabMain list
                row = self.caller.tabMain.myList.row
                name = self.caller.tabMain.current_mn[
                    self.caller.mnode_to_change['name']]
                self.caller.tabMain.myList.takeItem(row(name))
                self.caller.mnode_to_change = None

            # create new item
            new_masternode = {}
            new_masternode['name'] = self.ui.edt_name.text().strip()
            masternodeIp = self.ui.edt_masternodeIp.text().strip()
            if not masternodeIp.endswith('.onion'):
                masternodeIp = ip_address(masternodeIp).compressed
            new_masternode['ip'] = masternodeIp
            new_masternode['port'] = self.ui.edt_masternodePort.value()
            new_masternode['mnPrivKey'] = self.ui.edt_mnPrivKey.text().strip()
            new_masternode['hwAcc'] = self.ui.edt_hwAccount.value()
            new_masternode['isTestnet'] = 0 if not self.isTestnet() else 1

            coll = {}
            coll['address'] = self.ui.edt_address.text().strip()
            coll['spath'] = self.ui.edt_spath.value()
            coll['pubKey'] = self.ui.edt_pubKey.text().strip()
            coll['txid'] = self.ui.edt_txid.text().strip()
            coll['txidn'] = self.ui.edt_txidn.value()

            new_masternode['collateral'] = coll

            # add new item
            self.caller.masternode_list.append(new_masternode)
            # Write to file
            printDbg("saving MN configuration for %s" % new_masternode['name'])
            writeToFile(self.caller.masternode_list, masternodes_File)
            printDbg("saved")
            # Insert item in list of Main tab and connect buttons
            name = new_masternode['name']
            namelist = [x['name'] for x in self.caller.masternode_list]
            row = namelist.index(name)
            if row == -1:
                row = None
            self.caller.tabMain.insert_mn_list(name, new_masternode['ip'],
                                               new_masternode['port'], row)
            self.caller.tabMain.btn_remove[name].clicked.connect(
                lambda: self.caller.t_main.onRemoveMN())
            self.caller.tabMain.btn_edit[name].clicked.connect(
                lambda: self.caller.t_main.onEditMN())
            self.caller.tabMain.btn_start[name].clicked.connect(
                lambda: self.caller.t_main.onStartMN())
            self.caller.tabMain.btn_rewards[name].clicked.connect(
                lambda: self.caller.t_main.onRewardsMN())
            # go back
            self.onCancelMNConfig()

        except Exception as e:
            error_msg = "ERROR: %s" % e
            printDbg(error_msg)
            self.caller.myPopUp2(QMessageBox.Critical, 'ERROR', error_msg)
Esempio n. 14
0
    def onSendRewards(self):
        self.dest_addr = self.ui.destinationLine.text().strip()

        # Check dongle
        printDbg("Checking HW device")
        if self.caller.hwStatus != 2:
            self.caller.myPopUp2(QMessageBox.Critical, 'QMT - hw device check',
                                 "Connect to HW device first")
            printDbg(
                "Unable to connect to hardware device. The device status is: %d"
                % self.caller.hwStatus)
            return None

        # Check destination Address
        if not checkQmcAddr(self.dest_addr):
            self.caller.myPopUp2(
                QMessageBox.Critical, 'QMT - QMC address check',
                "The destination address is missing, or invalid.")
            return None

        # Check spending collateral
        if (not self.ui.collateralHidden
                and self.ui.rewardsList.box.collateralRow is not None
                and self.ui.rewardsList.box.item(
                    self.ui.rewardsList.box.collateralRow, 0).isSelected()):
            warning1 = "Are you sure you want to transfer the collateral?"
            warning2 = "Really?"
            warning3 = "Take a deep breath. Do you REALLY want to transfer your collateral?"
            ans = self.caller.myPopUp(QMessageBox.Warning, 'QMT - warning',
                                      warning1)
            if ans == QMessageBox.No:
                return None
            else:
                ans2 = self.caller.myPopUp(QMessageBox.Warning,
                                           'QMT - warning', warning2)
                if ans2 == QMessageBox.No:
                    return None
                else:
                    ans3 = self.caller.myPopUp(QMessageBox.Critical,
                                               'QMT - warning', warning3)
                    if ans3 == QMessageBox.No:
                        return None

        # LET'S GO
        if self.selectedRewards:
            printDbg("Sending from QMC address  %s  to QMC address  %s " %
                     (self.curr_addr, self.dest_addr))
            printDbg("Preparing transaction. Please wait...")
            self.ui.loadingLine.show()
            self.ui.loadingLinePercent.show()
            QApplication.processEvents()

            # save last destination address and swiftxCheck to cache
            self.caller.parent.cache["lastAddress"] = self.dest_addr
            self.caller.parent.cache["useSwiftX"] = self.useSwiftX()
            writeToFile(self.caller.parent.cache, cache_File)

            self.currFee = self.ui.feeLine.value() * 1e8

            try:
                self.txFinished = False
                self.caller.hwdevice.prepare_transfer_tx(
                    self.caller, self.curr_path, self.selectedRewards,
                    self.dest_addr, self.currFee, self.rawtransactions,
                    self.useSwiftX())

            except DisconnectedException as e:
                self.caller.hwStatus = 0
                self.caller.updateHWleds()

            except Exception as e:
                err_msg = "Error while preparing transaction. <br>"
                err_msg += "Probably Blockchain wasn't synced when trying to fetch raw TXs.<br>"
                err_msg += "<b>Wait for full synchronization</b> then hit 'Clear/Reload'"
                printException(getCallerName(), getFunctionName(), err_msg,
                               e.args)
        else:
            self.caller.myPopUp2(QMessageBox.Information,
                                 'Transaction NOT sent', "No UTXO to send")
def train(epoch):
    hawkEye.train()
    # empty the gradient buffer
    hawkEye.zero_grad()
    gradPresent = False

    # epochPS = 0
    # epochNS = 0
    # epochMC = 0
    # epochOAMC = 0
    # epochCL = 0
    # epochTL = 0

    for batchId, batch_data in enumerate(train_loader):
        st1 = time.time()

        data, targetCla, targetLoc, filenames = batch_data

        if data.size(0) < cnf.batchSize:
            del data
            del targetLoc
            del targetCla
            continue

        data = data.cuda(non_blocking=True)

        # pass data through network and predict
        cla, loc = hawkEye(data)

        targetClas = []
        targetLocs = []

        for i in range(cnf.batchSize):
            targetClas.append(targetCla[i].cuda(non_blocking=True))
            targetLocs.append(targetLoc[i].cuda(non_blocking=True))

        # compute loss, gradient, and optimize
        st = time.time()
        claLoss, locLoss, posClaLoss, negClaLoss, md, meanConfidence, overallMeanConfidence, ps, ns= \
         computeLoss(cla, loc, targetClas, targetLocs, None, None, args=args)
        ed = time.time()
        if claLoss is None:
            trainLoss = None
            tl = None
            cl = None
            ll = None
        elif locLoss is not None:
            trainLoss = claLoss + locLoss
            tl = trainLoss.item()
            cl = claLoss.item()
            ll = locLoss.item()
            posClaLoss = posClaLoss.item()
            negClaLoss = negClaLoss.item()
        else:
            trainLoss = claLoss
            tl = trainLoss.item()
            cl = claLoss.item()
            ll = None
            negClaLoss = negClaLoss.item()

        # trainLoss = claLoss+locLoss
        if trainLoss is not None:
            trainLoss.backward()
            gradPresent = gradPresent | True

        # gradients are accumulated over cnf.accumulationSteps
        if (batchId + 1) % cnf.accumulationSteps == 0 and gradPresent:
            gradNorm = misc.parameterNorm(hawkEye.parameters(), 'grad')
            weightNorm = misc.parameterNorm(hawkEye.parameters(), 'weight')
            misc.writeToFile(
                cnf.gradNormlog,
                cnf.normLogString.format(batchId + 1, epoch + 1, gradNorm,
                                         weightNorm))

            if args.clip and gradNorm > args.clipvalue:
                torch.nn.utils.clip_grad_norm_(hawkEye.parameters(),
                                               args.clipvalue)
            optimizer.step()
            hawkEye.zero_grad()

        if (batchId + 1) % cnf.accumulationSteps == 0:
            gradPresent = False

        ed1 = time.time()
        queue.put((epoch + 1, batchId + 1, cl, negClaLoss, posClaLoss, ll, tl,
                   int(ps), int(ns), md, meanConfidence, overallMeanConfidence,
                   ed - st, ed1 - st1))

        del data
        del targetClas
        del targetLocs
        del targetLoc
        del targetCla
        del filenames
    if os.path.isfile(cnf.model_file):
        hawkEye.load_state_dict(
            torch.load(cnf.model_file,
                       map_location=lambda storage, loc: storage))

    try:
        for epoch in range(cnf.epochs):
            # learning rate decay scheduler
            if args.step_lr:
                scheduler.step()

            st = time.time()
            train(epoch)
            ed = time.time()
            misc.writeToFile(
                cnf.trainlog2, '~~~~~epoch ' + str(epoch) +
                ' end time taken: ' + str(ed - st) + ' secs~~~~\n')

            # run validation every 10 epochs
            if args.val and (epoch + 1) % 5 == 0:
                validation(epoch)

            if (epoch + 1) % 3 == 0:
                torch.save(hawkEye.state_dict(), cnf.model_file)

    except BaseException as e:
        trace = traceback.format_exc()
        misc.writeToFile(cnf.errorlog, trace + '\n\n\n')
    finally:
        torch.save(hawkEye.state_dict(), cnf.model_file)
        del hawkEye