def verify_data(self):
        self.dmn_collateral_tx = self.edtCollateralTx.text().strip()
        try:
            self.dmn_collateral_tx_index = int(self.edtCollateralIndex.text())
            if self.dmn_collateral_tx_index < 0:
                raise Exception('Invalid transaction index')
        except Exception:
            self.edtCollateralIndex.setFocus()
            raise Exception(
                'Invalid collateral transaction index: should be integer greater or equal 0.'
            )

        try:
            self.dmn_ip = self.edtIP.text().strip()
            if self.dmn_ip:
                ipaddress.ip_address(self.dmn_ip)
        except Exception as e:
            self.edtIP.setFocus()
            raise Exception('Invalid masternode IP address: %s.' % str(e))

        try:
            if self.dmn_ip:
                self.dmn_tcp_port = int(self.edtPort.text())
            else:
                self.dmn_tcp_port = None
        except Exception:
            self.edtPort.setFocus()
            raise Exception('Invalid TCP port: should be integer.')

        self.dmn_owner_payout_addr = self.edtPayoutAddress.text().strip()
        if not validate_address(self.dmn_owner_payout_addr,
                                self.app_config.dash_network):
            self.edtPayoutAddress.setFocus()
            raise Exception('Invalid owner payout address.')

        if self.chbWholeMNReward.isChecked():
            self.dmn_operator_reward = 0
        else:
            self.dmn_operator_reward = self.edtOperatorReward.value()
            if self.dmn_operator_reward > 100 or self.dmn_operator_reward < 0:
                self.edtOperatorReward.setFocus()
                raise Exception(
                    'Invalid operator reward value: should be a value between 0 and 100.'
                )

        self.dmn_owner_privkey = self.edtOwnerKey.text().strip()
        if not validate_wif_privkey(self.dmn_owner_privkey,
                                    self.app_config.dash_network):
            self.edtOwnerKey.setFocus()
            self.upd_owner_key_info(True)
            raise Exception('Invalid owner private key.')
        else:
            self.dmn_owner_address = wif_privkey_to_address(
                self.dmn_owner_privkey, self.app_config.dash_network)

        try:
            self.dmn_operator_privkey = self.edtOperatorKey.text().strip()
            self.dmn_operator_pubkey = bls_privkey_to_pubkey(
                self.dmn_operator_privkey)
        except Exception as e:
            self.upd_operator_key_info(True)
            self.edtOperatorKey.setFocus()
            raise Exception('Invalid operator private key: ' + str(e))

        self.dmn_voting_privkey = self.edtVotingKey.text().strip()
        if not validate_wif_privkey(self.dmn_voting_privkey,
                                    self.app_config.dash_network):
            self.upd_voting_key_info(True)
            self.edtVotingKey.setFocus()
            raise Exception('Invalid voting private key.')
        else:
            self.dmn_voting_address = wif_privkey_to_address(
                self.dmn_voting_privkey, self.app_config.dash_network)

        self.btnContinue.setEnabled(False)
        self.btnContinue.repaint()

        ret = WndUtils.run_thread_dialog(self.get_collateral_tx_address_thread,
                                         (), True)
        self.btnContinue.setEnabled(True)
        self.btnContinue.repaint()
        return ret
Пример #2
0
def get_address_ext(hw_session: HwSessionInfo, bip32_path_n: List[int],
                    db_cursor: sqlite3.Cursor, encrypt_fun: Callable,
                    decrypt_fun: Callable):
    """
    Reads address of a specific bip32 path from hardware wallet, using db cache to speed-up operation
    by avoiding utilization the hardware wallet device as quite slow for this operation.
    :param hw_session:
    :param bip32_path_n:
    :param db_cursor:
    :param encrypt_fun:
    :param decrypt_fun:
    :return:
    """
    global hd_tree_db_map, bip32_address_map

    def get_hd_tree_db_id(tree_ident: str):
        db_id = hd_tree_db_map.get(tree_ident)
        if not db_id:
            db_cursor.execute('select id from ADDRESS_HD_TREE where ident=?',
                              (tree_ident, ))
            row = db_cursor.fetchone()
            if not row:
                db_cursor.execute(
                    'insert into ADDRESS_HD_TREE(ident) values(?)',
                    (tree_ident, ))
                db_id = db_cursor.lastrowid
                hd_tree_db_map[tree_ident] = db_id
            else:
                db_id = row[0]
        return db_id

    try:
        map_dict = bip32_address_map.get(hw_session.hd_tree_ident)
        if not map_dict:
            map_dict = {}
            bip32_address_map[hw_session.hd_tree_ident] = map_dict

        path_str = dash_utils.bip32_path_n_to_string(bip32_path_n)
        address = map_dict.get(path_str)
        db_id = None
        if not address:
            # look for address in db cache
            hd_tree_id = get_hd_tree_db_id(hw_session.hd_tree_ident)
            db_cursor.execute(
                'select id, address from ADDRESS where tree_id=? and path=?',
                (hd_tree_id, path_str))
            row = db_cursor.fetchone()
            if row:
                db_id, address = row
                # address is encrypted; try to decrypt it
                try:
                    address = decrypt_fun(address).decode('ascii')
                    if not dash_utils.validate_address(
                            address, hw_session.app_config.dash_network):
                        address = None
                except Exception:
                    address = None

            if not address:
                address = get_address(hw_session, bip32_path_n)
                map_dict[path_str] = address
                address_encrypted = encrypt_fun(bytes(address, 'ascii'))
                if db_id:
                    # update db record: it was encrypted with no longer valid encryption key
                    db_cursor.execute(
                        'update ADDRESS set address=? where id=?',
                        (address_encrypted, db_id))
                else:
                    db_cursor.execute(
                        'insert into ADDRESS(tree_id, path, address) values(?,?,?)',
                        (hd_tree_id, path_str, address_encrypted))
        return address
    except Exception as e:
        logging.exception('Unhandled exception occurred')
        return get_address(hw_session, bip32_path_n)
Пример #3
0
    def validate_data(self):
        payout_address = self.edtPayoutAddress.text()
        if payout_address:
            if not validate_address(payout_address,
                                    self.app_config.dash_network):
                raise Exception('Invalid payout address')
            else:
                self.dmn_new_payout_address = payout_address
        else:
            self.dmn_new_payout_address = self.dmn_prev_payout_address

        key = self.edtOperatorKey.text().strip()
        if key:
            if self.dmn_operator_key_type == InputKeyType.PRIVATE:
                self.dmn_new_operator_privkey = key

                try:
                    b = bytes.fromhex(self.dmn_new_operator_privkey)
                    if len(b) != 32:
                        raise Exception('invalid length (' + str(len(b)) + ')')
                except Exception as e:
                    self.edtOperatorKey.setFocus()
                    raise Exception('Invalid operator private key: ' + str(e))

                try:
                    self.dmn_new_operator_pubkey = bls_privkey_to_pubkey(
                        self.dmn_new_operator_privkey)
                except Exception as e:
                    self.edtOperatorKey.setFocus()
                    raise Exception('Invalid operator private key: ' + str(e))
            else:
                self.dmn_new_operator_pubkey = key
                self.dmn_new_operator_privkey = ''
                try:
                    b = bytes.fromhex(self.dmn_new_operator_pubkey)
                    if len(b) != 48:
                        raise Exception('invalid length (' + str(len(b)) + ')')
                except Exception as e:
                    self.edtOperatorKey.setFocus()
                    raise Exception('Invalid operator public key: ' + str(e))
        else:
            self.dmn_new_operator_pubkey = self.dmn_prev_operator_pubkey
            self.dmn_new_operator_privkey = ''

        key = self.edtVotingKey.text().strip()
        if key:
            if self.dmn_voting_key_type == InputKeyType.PRIVATE:
                self.dmn_new_voting_privkey = key
                if not validate_wif_privkey(self.dmn_new_voting_privkey,
                                            self.app_config.dash_network):
                    self.edtVotingKey.setFocus()
                    raise Exception('Invalid voting private key.')
                else:
                    self.dmn_new_voting_address = wif_privkey_to_address(
                        self.dmn_new_voting_privkey,
                        self.app_config.dash_network)
            else:
                self.dmn_new_voting_address = key
                self.dmn_new_voting_privkey = ''
                if not validate_address(self.dmn_new_voting_address,
                                        self.app_config.dash_network):
                    self.edtVotingKey.setFocus()
                    raise Exception('Invalid voting address.')
        else:
            self.dmn_new_voting_address = self.dmn_prev_voting_address
            self.dmn_new_voting_privkey = ''
    def read_from_file(self, file_name):
        try:
            file_info = {}
            data_decrypted = bytearray()
            for block in read_file_encrypted(file_name, file_info,
                                             self.hw_session):
                data_decrypted.extend(block)

            file_encrypted = file_info.get('encrypted', False)
            data = data_decrypted.decode('utf-8')

            addresses = []
            value_unit = None
            for line_idx, line in enumerate(data.split('\n')):
                if line:
                    elems = line.split('\t')
                    if len(elems) < 2:
                        elems = line.split(';')

                    if len(elems) < 2:
                        raise ValueError(
                            f'Invalid data file entry for line: {line_idx+1}.')

                    address = elems[0].strip()
                    value = elems[1].strip()

                    address_valid = dash_utils.validate_address(
                        address, dash_network=None)
                    if not address_valid:
                        if line_idx == 0 and re.match(r'^[A-Za-z_]+$',
                                                      address):
                            continue  # header line
                        else:
                            raise ValueError(
                                f'Invalid recipient address ({address}) (line {line_idx+1}).'
                            )

                    if value.endswith('%'):
                        vu = OUTPUT_VALUE_UNIT_PERCENT
                        value = value[:-1]
                    else:
                        vu = OUTPUT_VALUE_UNIT_AMOUNT
                    if value_unit is None:
                        value_unit = vu
                    elif value_unit != vu:
                        raise ValueError(
                            f'The value unit in line {line_idx+1} differs from the previous '
                            f'line.')

                    try:
                        if value:
                            value = float(value.replace(',', '.'))
                        else:
                            value = None
                        addresses.append((address, value))
                    except Exception as e:
                        raise ValueError(
                            f'Invalid data in the \'value\' field (line {line_idx+1}).'
                        )

            if len(addresses) == 0:
                raise Exception('File doesn\'t contain any recipient\'s data.')
            else:
                if self.values_unit != value_unit:
                    self.values_unit = value_unit
                    self.update_ui_value_unit()
                self.set_dest_addresses(addresses)
                self.current_file_name = file_name
                self.current_file_encrypted = file_encrypted
                self.add_menu_item_to_mru(self.current_file_name)
                self.update_mru_menu_items()
                self.update_change_amount()
                self.display_totals()
        except Exception as e:
            self.update_mru_menu_items()
            logging.exception(
                'Exception while reading file with recipients data.')
            self.parent_dialog.errorMsg(str(e))