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
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 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 lnd_poll(lnd: Lnd, progress_callback, password: str): client = LndClient(lnd) try: client.unlock(password) except _Rendezvous as e: details = e.details() log.warning('lnd_poll', details=details, exc_info=True) return details
def check(self): log.debug('datadir', datadir=self['datadir']) if (self['datadir'] is None or not os.path.exists(self['datadir'])): self.autoconfigure_datadir() if os.path.exists(os.path.join(self['datadir'], 'blocks')): if self['prune'] is None: self.set_prune(False) else: if self['prune'] is None: should_prune = self.hard_drives.should_prune(self['datadir']) self.set_prune(should_prune) self.wallet_paths = self.get_wallet_paths() if self['server'] is None: self['server'] = True if self['disablewallet'] is None and not self.wallet_paths: self['disablewallet'] = True elif self['disablewallet'] is None and self.wallet_paths: self['disablewallet'] = False if self['timeout'] is None: self['timeout'] = 6000 if self['rpcuser'] is None: self['rpcuser'] = '******' if self['rpcpassword'] is None: self['rpcpassword'] = get_random_password() self.zmq_block_port = get_zmq_port() self.zmq_tx_port = get_zmq_port() self['zmqpubrawblock'] = f'tcp://127.0.0.1:{self.zmq_block_port}' self['zmqpubrawtx'] = f'tcp://127.0.0.1:{self.zmq_tx_port}' self['proxy'] = '127.0.0.1:9050' self['listen'] = True self['bind'] = '127.0.0.1' self['debug'] = 'tor' self['discover'] = True # noinspection PyBroadException try: memory = psutil.virtual_memory() free_mb = round(memory.available / 1000000) free_mb -= int(free_mb * .3) if 'dbcache' in self: del self['dbcache'] self['dbcache'] = min(free_mb, 10000) self['maxmempool'] = 500 self['mempoolexpiry'] = 2000 except: log.warning('dbcache psutil.virtual_memory', exc_info=True) self['dbcache'] = 1000
def find_running_node(self) -> Optional[psutil.Process]: self.is_unlocked = False self.running = False self.process = None found_ports = [] try: processes = psutil.process_iter() except: log.warning('Lnd.find_running_node', exc_info=True) return None for process in processes: if not process.is_running(): log.warning('Lnd.find_running_node', exc_info=True) continue try: process_name = process.name() except: log.warning('Lnd.find_running_node', exc_info=True) continue if 'lnd' in process_name: lnd_process = process open_files = None try: open_files = lnd_process.open_files() log_file = open_files[0] except: log.warning('Lnd.find_running_node', open_files=open_files, exc_info=True) continue if str(self.bitcoin.network) not in log_file.path: continue self.process = lnd_process self.running = True try: is_unlocked = False connections = process.connections() for connection in connections: found_ports.append( (connection.laddr, connection.raddr)) if 8080 <= connection.laddr.port <= 9000: self.rest_port = connection.laddr.port elif 10009 <= connection.laddr.port <= 10100: self.grpc_port = connection.laddr.port elif 9735 <= connection.laddr.port < 9800: self.node_port = connection.laddr.port is_unlocked = True self.is_unlocked = is_unlocked return lnd_process except: log.warning('Lnd.find_running_node', exc_info=True) continue return None
def find_running_node(self) -> Optional[psutil.Process]: # noinspection PyBroadException try: processes = psutil.process_iter() except: log.warning('Bitcoin.find_running_node', exc_info=True) return None for process in processes: try: if not process.is_running() or process.status() == 'zombie': continue except: log.warning('Bitcoin.find_running_node', exc_info=True) continue # noinspection PyBroadException try: process_name = process.name() except: log.warning('Bitcoin.find_running_node', exc_info=True) continue if 'bitcoin' in process_name: # noinspection PyBroadException try: for connection in process.connections(): ports = [self.rpc_port, self.node_port] if connection.laddr.port in ports: self.running = True return process except: log.warning('Bitcoin.find_running_node', exc_info=True) continue return None
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
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
def get_dir_size(self, start_path: str) -> int: total_size = 0 entries = None try: entries = os.scandir(start_path) for entry in entries: if entry.is_dir(follow_symlinks=False): total_size += self.get_dir_size(entry.path) elif entry.is_file(follow_symlinks=False): total_size += entry.stat().st_size except: log.warning('get_dir_size', start_path=start_path, total_size=total_size, entries=entries, exc_info=True) return total_size
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
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()
def __init__(self, configuration_file_path: str): self.hard_drives = HardDrives() self.software = BitcoinSoftware() self.file = ConfigurationFile(configuration_file_path) self.running = False self.process = None if self.file['datadir'] is None: self.autoconfigure_datadir() if 'bitcoin.conf' in os.listdir(self.file['datadir']): actual_conf_file = os.path.join(self.file['datadir'], 'bitcoin.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() 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_bitcoin=True) self.set_prune(should_prune) if not self.detect_zmq_ports(): 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.check_process()
def check(self): log.debug('datadir', datadir=self.file['datadir']) if (self.file['datadir'] is None or not os.path.exists(self.file['datadir'])): self.autoconfigure_datadir() if 'bitcoin.conf' in os.listdir(self.file['datadir']): actual_conf_file = os.path.join(self.file['datadir'], 'bitcoin.conf') if self.file_path != actual_conf_file: log.info('datadir_redirect', configuration_file_path=self.file_path, actual_conf_file=actual_conf_file) self.file = ConfigurationFile(actual_conf_file) if (self.file['datadir'] is None or not os.path.exists(self.file['datadir'])): 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_bitcoin=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}' self.file['proxy'] = '127.0.0.1:9050' self.file['listen'] = True self.file['bind'] = '127.0.0.1' self.file['debug'] = 'tor' self.file['discover'] = True # 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()