Beispiel #1
0
 def handle_unlock_wallet(self, details: str):
     if details is None:
         return
     details = details.lower()
     # The Wallet Unlocker gRPC service disappears from LND's API
     # after the wallet is unlocked (or created/recovered)
     if 'unknown service lnrpc.walletunlocker' in details:
         pass
     # User needs to create a new wallet
     elif 'wallet not found' in details:
         new_wallet_password = get_random_password()
         keyring_service_name = keyring_user_name = f'lnd_wallet_password'
         log.info('create_wallet',
                  keyring_service_name=keyring_service_name,
                  keyring_user_name=keyring_user_name)
         keyring.set_password(service=keyring_service_name,
                              username=keyring_user_name,
                              password=new_wallet_password)
         seed = self.generate_seed(new_wallet_password)
         try:
             self.lnd.client.initialize_wallet(
                 wallet_password=new_wallet_password,
                 seed=seed,
                 seed_password=new_wallet_password)
         except _Rendezvous:
             log.error('initialize_wallet error', exc_info=True)
             raise
         keyring.set_password(service=f'lnd_mainnet_wallet_password',
                              username=self.lnd.file['bitcoind.rpcuser'],
                              password=new_wallet_password)
     else:
         log.warning('unlock_wallet failed', details=details, exc_info=True)
    def __init__(self):
        file_name = 'litecoin.conf'
        litecoin_data_path = LITECOIN_DATA_PATH[OPERATING_SYSTEM]
        self.litecoin_configuration_file_path = os.path.join(litecoin_data_path,
                                                            file_name)
        log.info(
            'litecoin_configuration_file_path',
            litecoin_configuration_file_path=self.litecoin_configuration_file_path
        )
        self.litecoin = Litecoin(
            configuration_file_path=self.litecoin_configuration_file_path
        )

        file_name = 'lnd-ltc.conf'
        lnd_dir_path = LND_DIR_PATH[OPERATING_SYSTEM]
        self.lnd_configuration_file_path = os.path.join(lnd_dir_path, file_name)
        log.info(
            'lnd_configuration_file_path',
            lnd_configuration_file_path=self.lnd_configuration_file_path
        )
        self.lnd = Lnd(
            configuration_file_path=self.lnd_configuration_file_path,
            litecoin=self.litecoin
        )
        self.lnd_client = LndClient(self.lnd)
    def generate_seed(self, new_seed_password: str):
        try:
            generate_seed_response = self.client.generate_seed(
                seed_password=new_seed_password
            )
        except _Rendezvous:
            log.error('generate_seed error', exc_info=True)
            raise

        seed = generate_seed_response.cipher_seed_mnemonic

        keyring_service_name = f'lnd_seed'
        keyring_user_name = ''.join(seed[0:2])
        log.info(
            'generate_seed',
            keyring_service_name=keyring_service_name,
            keyring_user_name=keyring_user_name
        )

        keyring.set_password(
            service=keyring_service_name,
            username=keyring_user_name,
            password='******'.join(seed)
        )

        keyring.set_password(
            service=f'{keyring_service_name}_seed_password',
            username=keyring_user_name,
            password=new_seed_password
        )
        return seed
Beispiel #4
0
 def handle_unlock_wallet(self, details: str):
     if details is None:
         return
     details = details.lower()
     # The Wallet Unlocker gRPC service disappears from LND's API
     # after the wallet is unlocked (or created/recovered)
     if 'unknown service lnrpc.walletunlocker' in details:
         pass
     # User needs to create a new wallet
     elif 'wallet not found' in details:
         new_wallet_password = get_random_password()
         keyring_service_name = keyring_user_name = f'lnd_wallet_password'
         log.info('create_wallet',
                  keyring_service_name=keyring_service_name,
                  keyring_user_name=keyring_user_name)
         keyring.set_password(service=keyring_service_name,
                              username=keyring_user_name,
                              password=new_wallet_password)
         seed = self.generate_seed(new_wallet_password)
         try:
             self.node_set.lnd_client.initialize_wallet(
                 wallet_password=new_wallet_password,
                 seed=seed,
                 seed_password=new_wallet_password)
         except _Rendezvous as e:
             log.error('initialize_wallet', exc_info=True)
             # noinspection PyProtectedMember
             self.error_message.showMessage(e._state.details)
             return
         keyring.set_password(
             service=f'lnd_{self.node_set.litecoin.network}_wallet_password',
             username=self.node_set.litecoin.file['rpcuser'],
             password=new_wallet_password)
     else:
         log.warning('unlock_wallet failed', details=details, exc_info=True)
    def __init__(self, path, **kwargs):
        super().__init__(**kwargs)
        self.path = path
        parent = os.path.abspath(os.path.join(path, pardir))
        if not isdir(parent):
            log.info('Creating directory', path=parent)
            os.mkdir(parent)
        if not isfile(self.path):
            log.info('Creating file', path=self.path)
            with open(self.path, 'w') as f:
                f.write('# Auto-Generated Configuration File' + os.linesep +
                        os.linesep)
                f.write(f'# Node Launcher version {NODE_LAUNCHER_RELEASE}' +
                        os.linesep + os.linesep)
                f.flush()

        self.cache = {}
        self.aliases = {
            'rpcport': 'main.rpcport',
            'main.rpcport': 'rpcport',
            'port': 'main.port',
            'main.port': 'port',
            'walletdir': 'main.walletdir',
            'main.walletdir': 'walletdir'
        }
        self.populate_cache()
        self.file_watcher = QFileSystemWatcher()
        self.file_watcher.addPath(self.path)
Beispiel #6
0
    def unlock_wallet(self):
        password = self.password_prompt(
            title=f'Unlock {self.node_set.bitcoin.network} LND Wallet',
            label='Wallet Password')

        try:
            self.node_set.lnd_client.unlock(wallet_password=password)
        except _Rendezvous as e:
            log.error('unlock_wallet', exc_info=True)
            # noinspection PyProtectedMember
            self.error_message.showMessage(e._state.details)
            return

        timestamp = str(time.time())
        keyring_service_name = f'lnd_{self.node_set.bitcoin.network}_wallet_password'
        log.info('unlock_wallet',
                 keyring_service_name=keyring_service_name,
                 keyring_user_name=timestamp)

        keyring.set_password(service=keyring_service_name,
                             username=timestamp,
                             password=password)

        keyring.set_password(service=keyring_service_name,
                             username=self.node_set.bitcoin.file['rpcuser'],
                             password=password)
Beispiel #7
0
    def generate_seed(self, new_seed_password: str):
        try:
            generate_seed_response = self.node_set.lnd_client.generate_seed(
                seed_password=new_seed_password)
        except _Rendezvous as e:
            log.error('generate_seed', exc_info=True)
            # noinspection PyProtectedMember
            self.error_message.showMessage(e._state.details)
            return

        seed = generate_seed_response.cipher_seed_mnemonic

        keyring_service_name = f'lnd_seed'
        keyring_user_name = ''.join(seed[0:2])
        log.info('generate_seed',
                 keyring_service_name=keyring_service_name,
                 keyring_user_name=keyring_user_name)

        keyring.set_password(service=keyring_service_name,
                             username=keyring_user_name,
                             password='******'.join(seed))

        keyring.set_password(service=f'{keyring_service_name}_seed_password',
                             username=keyring_user_name,
                             password=new_seed_password)
        return seed
Beispiel #8
0
 def should_prune(input_directory: str, has_bitcoin: bool) -> bool:
     directory = os.path.realpath(input_directory)
     try:
         total, used, free, percent = psutil.disk_usage(os.path.realpath(directory))
     except:
         log.warning(
             'should_prune_disk_usage',
             input_directory=input_directory,
             directory=directory,
             exc_info=True
         )
         return False
     if has_bitcoin:
         bitcoin_bytes = get_dir_size(directory)
         free += bitcoin_bytes
     else:
         bitcoin_bytes = 0
     free_gb = math.floor(free / GIGABYTE)
     bitcoin_gb = math.ceil(bitcoin_bytes / GIGABYTE)
     free_gb += bitcoin_gb
     should_prune = free_gb < AUTOPRUNE_GB
     log.info(
         'should_prune',
         input_directory=input_directory,
         has_bitcoin=has_bitcoin,
         total=total,
         used=used,
         free=free,
         bitcoin_bytes=bitcoin_bytes,
         percent=percent,
         free_gb=free_gb,
         bitcoin_gb=bitcoin_gb,
         should_prune=should_prune
     )
     return should_prune
Beispiel #9
0
    def set_button_state(self):
        old_state = self.state
        if self.node_set.lnd.running and not self.node_set.lnd.is_unlocked:
            if self.node_set.lnd.has_wallet:
                if self.state != 'unlock':
                    self.set_unlock_state()
                    self.auto_unlock_wallet()
                else:
                    return
            else:
                if self.state != 'create':
                    self.set_create_recover_state()
                else:
                    return
        elif self.node_set.lnd.running and self.node_set.lnd.is_unlocked:
            if self.state != 'open':
                self.set_open_state()
            else:
                return
        elif not self.node_set.lnd.running:
            self.node_set.lnd.is_unlocked = False
            if self.state != 'closed':
                self.set_closed_state()
            else:
                return

        log.info('set_button_state',
                 lnd_is_running=self.node_set.lnd.running,
                 lnd_is_unlocked=self.node_set.lnd.is_unlocked,
                 lnd_has_wallet=self.node_set.lnd.has_wallet,
                 old_state=old_state,
                 new_state=self.state)
    def read(self) -> List[Tuple[str, str, str]]:
        parent = os.path.abspath(os.path.join(self.path, pardir))

        if not isdir(parent):
            log.info('Creating directory', path=parent)
            os.makedirs(parent)

        if not isfile(self.path):
            log.info('Creating file', path=self.path)
            lines = [
                '# Auto-Generated Configuration File' + os.linesep +
                os.linesep,
                f'# Node Launcher version {NODE_LAUNCHER_RELEASE}' +
                os.linesep + os.linesep
            ]
            with open(self.path, 'w') as f:
                f.writelines(lines)

        with open(self.path, 'r') as f:
            lines = f.readlines()

        parsed_lines = []
        index = 0
        for line in lines:
            key, value = self.parse_line(line)
            if key:
                parsed_lines.append((str(index), key, value))
                index += 1

        return parsed_lines
Beispiel #11
0
    def run_command(self, cmd: str):
        log.info(
            'run_command',
            program=self.program,
            args=self.args,
            cmd=cmd
        )
        self.output.append(f'> {cmd}\n')
        self.input.clear()

        process = QProcess()
        process.setProgram(self.program)
        process.setCurrentReadChannel(0)

        # noinspection PyUnresolvedReferences
        process.readyReadStandardError.connect(
            lambda: self.handle_error(process)
        )
        # noinspection PyUnresolvedReferences
        process.readyReadStandardOutput.connect(
            lambda: self.handle_output(process)
        )

        connect_args = list(self.args)

        args = cmd.split(' ')
        if args[0] == self.program.split('/')[-1]:
            args.pop(0)
        process.setArguments(connect_args + args)
        process.start()
Beispiel #12
0
 def get_big_drive(self) -> Partition:
     partitions = self.list_partitions()
     max_free_space = max([p.gb_free for p in partitions])
     for partition in partitions:
         if partition.gb_free == max_free_space:
             log.info('get_big_drive', partition=partition)
             return partition
Beispiel #13
0
 def lnd(self) -> List[str]:
     command = [self.software.lnd, f'--configfile="{self.file.path}"']
     if self.bitcoin.file['testnet']:
         command += ['--bitcoin.testnet']
     else:
         command += ['--bitcoin.mainnet']
     log.info('lnd', command=command, **self.file.cache)
     return command
 def load(self):
     file_name = 'torrc'
     tor_dir_path = TOR_DIR_PATH[OPERATING_SYSTEM]
     configuration_file_path = os.path.join(tor_dir_path, file_name)
     log.info('Loading tor configuration file',
              configuration_file_path=configuration_file_path)
     self.file = ConfigurationFile(path=configuration_file_path,
                                   assign_op=' ')
Beispiel #15
0
 def run_command(self, cmd: str):
     log.info('run_command', program=self.program, args=self.args, cmd=cmd)
     self.output.append(f'> {cmd}\n')
     self.input.clear()
     self.process.kill()
     args = list(self.args)
     args.append(cmd)
     self.process.setArguments(args)
     self.process.start()
Beispiel #16
0
 def bitcoin_qt(self) -> List[str]:
     command = [self.software.bitcoin_qt]
     args = [
         f'-conf={self.file.path}',
     ]
     if IS_WINDOWS:
         args = [
             f'-conf="{self.file.path}"',
         ]
     command += args
     log.info('bitcoin_qt', command=command, **self.file.cache)
     return command
Beispiel #17
0
 def auto_unlock_wallet(self):
     keyring_service_name = f'lnd_mainnet_wallet_password'
     keyring_user_name = self.lnd.file['bitcoind.rpcuser']
     log.info('auto_unlock_wallet_get_password',
              keyring_service_name=keyring_service_name,
              keyring_user_name=keyring_user_name)
     password = keyring.get_password(
         service=keyring_service_name,
         username=keyring_user_name,
     )
     worker = Worker(fn=self.unlock_wallet, lnd=self.lnd, password=password)
     worker.signals.result.connect(self.handle_unlock_wallet)
     self.threadpool.start(worker)
Beispiel #18
0
    def autoconfigure_datadir(self):
        default_datadir = BITCOIN_DATA_PATH[OPERATING_SYSTEM]
        big_drive = self.hard_drives.get_big_drive()
        default_is_big_enough = not self.hard_drives.should_prune(
            input_directory=default_datadir
        )
        default_is_biggest = self.hard_drives.is_default_partition(big_drive)
        log.info(
            'autoconfigure_datadir',
            default_is_big_enough=default_is_big_enough,
            default_is_biggest=default_is_biggest
        )
        if default_is_big_enough or default_is_biggest:
            self['datadir'] = default_datadir
            log.info(
                'autoconfigure_datadir',
                datadir=default_datadir
            )
            return

        if not self.hard_drives.should_prune(big_drive.mountpoint):
            datadir = os.path.join(big_drive.mountpoint, 'Bitcoin')
            self['datadir'] = datadir
            log.info(
                'autoconfigure_datadir',
                datadir=datadir
            )
            if not os.path.exists(self['datadir']):
                os.mkdir(self['datadir'])
        else:
            self['datadir'] = default_datadir
            log.info(
                'autoconfigure_datadir',
                datadir=default_datadir
            )
Beispiel #19
0
    def recover_wallet(self):
        title = f'Recover {self.node_set.bitcoin.network} LND Wallet'
        new_wallet_password = self.get_new_password(title=title,
                                                    password_name='LND Wallet')

        seed_password = self.password_prompt(title=title,
                                             label='Seed Password (Optional)')

        seed, ok = QInputDialog.getText(
            self.password_dialog, title,
            'Mnemonic Seed (one line with spaces)')
        if not ok:
            raise Exception()
        seed_list = seed.split(' ')

        keyring_service_name = f'lnd_{self.node_set.bitcoin.network}'
        keyring_user_name = str(time.time())
        log.info('recover_wallet',
                 keyring_service_name=keyring_service_name,
                 keyring_user_name=keyring_user_name)

        keyring.set_password(service=f'{keyring_service_name}_wallet_password',
                             username=keyring_user_name,
                             password=new_wallet_password)
        keyring.set_password(service=f'{keyring_service_name}_seed',
                             username=keyring_user_name,
                             password=seed)
        if seed_password is not None:
            keyring.set_password(
                service=f'{keyring_service_name}_seed_password',
                username=keyring_user_name,
                password=seed_password)

        try:
            self.node_set.lnd_client.initialize_wallet(
                wallet_password=new_wallet_password,
                seed=seed_list,
                seed_password=seed_password,
                recovery_window=10000)
        except _Rendezvous as e:
            log.error('recover_wallet_initialize_wallet', exc_info=True)
            # noinspection PyProtectedMember
            self.error_message.showMessage(e._state.details)
            return

        keyring.set_password(
            service=f'lnd_{self.node_set.bitcoin.network}_wallet_password',
            username=self.node_set.bitcoin.file['rpcuser'],
            password=new_wallet_password)
 def auto_unlock_wallet(self):
     keyring_service_name = f'lnd_mainnet_wallet_password'
     keyring_user_name = self.configuration['bitcoind.rpcuser']
     log.info('auto_unlock_wallet_get_password',
              keyring_service_name=keyring_service_name,
              keyring_user_name=keyring_user_name)
     password = self.keyring.get_password(
         service=keyring_service_name,
         username=keyring_user_name,
     )
     worker = Worker(fn=self.unlock_wallet,
                     configuration=self.configuration,
                     password=password)
     worker.signals.result.connect(self.handle_unlock_wallet)
     QThreadPool().start(worker)
Beispiel #21
0
 def list_partitions(self) -> List[Partition]:
     partitions = []
     try:
         ps = psutil.disk_partitions()
     except:
         log.warning('list_partitions', exc_info=True)
         return partitions
     partition_paths = [
         p.mountpoint for p in ps if 'removable' not in p.opts
     ]
     log.info('partition_paths', partition_paths=partition_paths)
     for path in partition_paths:
         free_gb = self.get_gb(path)
         partitions.append(Partition(path, free_gb), )
     return partitions
Beispiel #22
0
 def auto_unlock_wallet(self):
     keyring_service_name = f'lnd_{self.node_set.bitcoin.network}_wallet_password'
     keyring_user_name = self.node_set.bitcoin.file['rpcuser']
     log.info('auto_unlock_wallet_get_password',
              keyring_service_name=keyring_service_name,
              keyring_user_name=keyring_user_name)
     password = keyring.get_password(
         service=keyring_service_name,
         username=keyring_user_name,
     )
     if password is not None:
         worker = Worker(fn=self.lnd_poll,
                         lnd=self.node_set.lnd,
                         password=password)
         worker.signals.result.connect(self.handle_lnd_poll)
         self.threadpool.start(worker)
Beispiel #23
0
    def get_gb(path: str) -> int:
        try:
            capacity, used, free, percent = psutil.disk_usage(path)
        except:
            log.warning('get_gb', path=path, exc_info=True)
            return 0

        free_gb = math.floor(free / GIGABYTE)
        log.info('get_gb',
                 path=path,
                 capacity=capacity,
                 used=used,
                 free=free,
                 percent=percent,
                 free_gb=free_gb)
        return free_gb
Beispiel #24
0
    def __init__(self, path, **kwargs):
        super().__init__(**kwargs)
        self.path = path
        parent = os.path.abspath(os.path.join(path, pardir))
        if not isdir(parent):
            log.info('Creating directory', path=parent)
            os.mkdir(parent)
        if not isfile(self.path):
            log.info('Creating file', path=self.path)
            with open(self.path, 'w') as f:
                f.write('# Auto-Generated Configuration File' + os.linesep +
                        os.linesep)
                f.write(f'# Node Launcher version {NODE_LAUNCHER_RELEASE}' +
                        os.linesep + os.linesep)
                f.flush()

        self.cache = {}
        self.populate_cache()
 def read(self) -> List[Tuple[str, str]]:
     parent = os.path.abspath(os.path.join(self.path, pardir))
     if not isdir(parent):
         log.info('Creating directory', path=parent)
         os.makedirs(parent)
     if not isfile(self.path):
         log.info('Creating file', path=self.path)
         lines = [
             '# Auto-Generated Configuration File' + os.linesep +
             os.linesep,
             f'# Node Launcher version {NODE_LAUNCHER_RELEASE}' +
             os.linesep + os.linesep
         ]
         with open(self.path, 'w') as f:
             f.writelines(lines)
     with open(self.path, 'r') as f:
         lines = f.readlines()
     parsed_lines = [self.parse_line(l) for l in lines]
     return [l for l in parsed_lines if l[0]]
Beispiel #26
0
    def __init__(self):
        file_name = 'bitcoin.conf'
        bitcoin_data_path = BITCOIN_DATA_PATH[OPERATING_SYSTEM]
        self.bitcoin_configuration_file_path = os.path.join(
            bitcoin_data_path, file_name)
        log.info('bitcoin_configuration_file_path',
                 bitcoin_configuration_file_path=self.
                 bitcoin_configuration_file_path)
        self.bitcoin = Bitcoin(
            configuration_file_path=self.bitcoin_configuration_file_path)

        file_name = 'lnd.conf'
        lnd_dir_path = LND_DIR_PATH[OPERATING_SYSTEM]
        self.lnd_configuration_file_path = os.path.join(
            lnd_dir_path, file_name)
        log.info('lnd_configuration_file_path',
                 lnd_configuration_file_path=self.lnd_configuration_file_path)
        self.lnd = Lnd(
            configuration_file_path=self.lnd_configuration_file_path,
            bitcoin=self.bitcoin)
Beispiel #27
0
 def should_prune(input_directory: str) -> bool:
     directory = os.path.realpath(input_directory)
     try:
         total, used, free, percent = psutil.disk_usage(directory)
     except:
         log.warning('should_prune_disk_usage',
                     input_directory=input_directory,
                     directory=directory,
                     exc_info=True)
         return False
     free_gb = math.floor(free / GIGABYTE)
     should_prune = free_gb < AUTOPRUNE_GB
     log.info('should_prune',
              input_directory=input_directory,
              total=total,
              used=used,
              free=free,
              percent=percent,
              free_gb=free_gb,
              should_prune=should_prune)
     return should_prune
Beispiel #28
0
    def run_command(self, command):
        try:
            if self.cli is None or self.cli_args is None:
                self.output_area.append(
                    'Node starting up, please try again later...')
                return False

            self.output_area.append(f'> {command}\n')

            process = QProcess()
            process.setProgram(self.cli)
            process.setCurrentReadChannel(0)

            # noinspection PyUnresolvedReferences
            process.readyReadStandardError.connect(
                lambda: self.handle_cli_error_output(process))

            # noinspection PyUnresolvedReferences
            process.readyReadStandardOutput.connect(
                lambda: self.handle_cli_output(process))

            args = command.split(' ')
            if args[0] == self.cli.split('/')[-1]:
                args.pop(0)
            process.setArguments(self.cli_args + args)
            process.start()

            log.info('run_command',
                     program=self.cli,
                     args=self.cli_args,
                     cmd=command)

            return True
        except Exception:
            self.output_area.append(
                'Node starting up, please try again later...')
            return False
Beispiel #29
0
    def create_wallet(self):
        new_wallet_password = self.get_new_password(
            title=f'Create {self.node_set.bitcoin.network} LND Wallet',
            password_name='LND Wallet')

        keyring_service_name = f'lnd_{self.node_set.bitcoin.network}_wallet_password'
        keyring_user_name = str(time.time())
        log.info('create_wallet',
                 keyring_service_name=keyring_service_name,
                 keyring_user_name=keyring_user_name)

        keyring.set_password(service=keyring_service_name,
                             username=keyring_user_name,
                             password=new_wallet_password)

        new_seed_password = self.get_new_password(
            title=f'Create {self.node_set.bitcoin.network} LND Wallet',
            password_name='Mnemonic Seed')

        seed = self.generate_seed(new_seed_password)
        self.backup_seed(seed)

        try:
            self.node_set.lnd_client.initialize_wallet(
                wallet_password=new_wallet_password,
                seed=seed,
                seed_password=new_seed_password)
        except _Rendezvous as e:
            log.error('initialize_wallet', exc_info=True)
            # noinspection PyProtectedMember
            self.error_message.showMessage(e._state.details)
            return

        keyring.set_password(
            service=f'lnd_{self.node_set.bitcoin.network}_wallet_password',
            username=self.node_set.bitcoin.file['rpcuser'],
            password=new_wallet_password)
    def __init__(self, configuration_file_path: str):
        self.hard_drives = HardDrives()
        self.software = LitecoinSoftware()
        self.file = ConfigurationFile(configuration_file_path)
        self.running = False
        self.process = None

        if self.file['datadir'] is None:
            self.autoconfigure_datadir()

        if 'litecoin.conf' in os.listdir(self.file['datadir']):
            actual_conf_file = os.path.join(self.file['datadir'], 'litecoin.conf')
            log.info(
                'datadir_redirect',
                configuration_file_path=configuration_file_path,
                actual_conf_file=actual_conf_file
            )
            self.file = ConfigurationFile(actual_conf_file)
            if self.file['datadir'] is None:
                self.autoconfigure_datadir()

        if os.path.exists(os.path.join(self.file['datadir'], 'blocks')):
            if self.file['prune'] is None:
                self.set_prune(False)

        self.wallet_paths = self.get_wallet_paths()

        if self.file['server'] is None:
            self.file['server'] = True

        if self.file['disablewallet'] is None and not self.wallet_paths:
            self.file['disablewallet'] = True
        elif self.file['disablewallet'] is None and self.wallet_paths:
            self.file['disablewallet'] = False

        if self.file['timeout'] is None:
            self.file['timeout'] = 6000

        if self.file['rpcuser'] is None:
            self.file['rpcuser'] = '******'

        if self.file['rpcpassword'] is None:
            self.file['rpcpassword'] = get_random_password()

        if self.file['prune'] is None:
            should_prune = self.hard_drives.should_prune(self.file['datadir'], has_litecoin=True)
            self.set_prune(should_prune)

        self.zmq_block_port = get_zmq_port()
        self.zmq_tx_port = get_zmq_port()

        self.file['zmqpubrawblock'] = f'tcp://127.0.0.1:{self.zmq_block_port}'
        self.file['zmqpubrawtx'] = f'tcp://127.0.0.1:{self.zmq_tx_port}'

        # noinspection PyBroadException
        try:
            memory = psutil.virtual_memory()
            free_mb = round(memory.available / 1000000)
            free_mb -= int(free_mb * .3)
            self.file['dbcache'] = free_mb
        except:
            log.warning(
                'dbcache psutil.virtual_memory',
                exc_info=True
            )
            self.file['dbcache'] = 1000

        self.config_snapshot = self.file.snapshot.copy()
        self.file.file_watcher.fileChanged.connect(self.config_file_changed)

        self.process = QProcess()
        self.process.setProgram(self.software.litecoind)
        self.process.setCurrentReadChannel(0)
        self.process.setArguments(self.args)
        self.process.start()