def test_set_rpcuser(litecoin: Litecoin): litecoin.file['rpcuser'] = '******' changed = ConfigurationFile(litecoin.file.path) assert changed['rpcuser'] == 'test_user' litecoin.file['rpcuser'] = '******' changed_again = ConfigurationFile(litecoin.file.path) assert changed_again['rpcuser'] == 'test_user_2'
def test_setattr_bool(self, configuration_file: ConfigurationFile): configuration_file.test_bool_false = False configuration_file.test_bool_true = True with open(configuration_file.path, 'r') as f: text = f.read() assert 'test_bool_false=0' in text assert 'test_bool_true=1' in text
def test_set_rpcuser(bitcoin: Bitcoin): bitcoin.file.rpcuser = '******' changed = ConfigurationFile(bitcoin.file.path) assert changed.rpcuser == 'test_user' bitcoin.file.rpcuser = '******' changed_again = ConfigurationFile(bitcoin.file.path) assert changed_again.rpcuser == 'test_user_2'
def test_set_prune(bitcoin: Bitcoin): bitcoin.set_prune(True) pruned = ConfigurationFile(bitcoin.file.path) assert pruned.prune assert not pruned.txindex bitcoin.set_prune(False) unpruned = ConfigurationFile(bitcoin.file.path) assert not unpruned.prune assert unpruned.txindex
def test_set_prune(litecoin: Litecoin): litecoin.set_prune(True) pruned = ConfigurationFile(litecoin.file.path) assert pruned['prune'] assert not pruned['txindex'] litecoin.set_prune(False) unpruned = ConfigurationFile(litecoin.file.path) assert not unpruned['prune'] assert unpruned['txindex']
def __init__(self, network: str, configuration_file_path: str): self.network = network self.hard_drives = HardDrives() self.software = BitcoinSoftware() self.file = ConfigurationFile(configuration_file_path) self.process = self.find_running_node() if self.file.rpcuser is None: self.file.rpcuser = '******' if self.file.rpcpassword is None: self.file.rpcpassword = get_random_password() if self.file.datadir is None: self.autoconfigure_datadir() 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() if self.file.dbcache is None: # noinspection PyBroadException try: memory = psutil.virtual_memory() free_mb = round(memory.available / 1000000) self.file.dbcache = free_mb except: self.file.dbcache = 1000
def __init__(self, configuration_file_path: str, lnd: Lnd): self.lnd = lnd self.bitcoin = lnd.bitcoin self.file = ConfigurationFile(configuration_file_path, ' ') #self.software = TorSoftware() self.tordir = TOR_DIR_PATH[OPERATING_SYSTEM] # torrc edits self.file['ControlPort'] = '9051' self.file['CookieAuthentication'] = '1' self.file['HiddenServiceDir'] = os.path.join(self.tordir, 'bitcoin-service') self.file['HiddenServicePort'] = '8333 127.0.0.1:8333' self.file['HiddenServicePort'] = '18333 127.0.0.1:18333' # bitcoin.conf edits self.bitcoin.file['proxy'] = '127.0.0.1:9050' self.bitcoin.file['listen'] = '1' self.bitcoin.file['bind'] = '127.0.0.1' self.bitcoin.file['debug'] = 'tor' # lnd.conf edits self.lnd.file['listen'] = 'localhost' self.lnd.file['tor.active'] = '1' self.lnd.file['tor.v3'] = '1' self.lnd.file['tor.streamisolation'] = '1'
def __init__(self, network: Network, configuration_file_path: str, bitcoin: Bitcoin): self.running = False self.is_unlocked = False self.network = network self.bitcoin = bitcoin self.file = ConfigurationFile(configuration_file_path) self.process = self.find_running_node() self.software = LndSoftware() self.file['lnddir'] = LND_DIR_PATH[OPERATING_SYSTEM] if self.file['debuglevel'] is None: self.file['debuglevel'] = 'info' self.file['bitcoin.active'] = True self.file['bitcoin.node'] = 'bitcoind' self.file['bitcoind.rpchost'] = '127.0.0.1' self.file['bitcoind.rpcuser'] = self.bitcoin.file['rpcuser'] self.file['bitcoind.rpcpass'] = self.bitcoin.file['rpcpassword'] self.file['bitcoind.zmqpubrawblock'] = self.bitcoin.file[ 'zmqpubrawblock'] self.file['bitcoind.zmqpubrawtx'] = self.bitcoin.file['zmqpubrawtx'] if self.file['restlisten'] is None: if self.network == TESTNET: self.rest_port = get_port(LND_DEFAULT_REST_PORT + 1) else: self.rest_port = get_port(LND_DEFAULT_REST_PORT) self.file['restlisten'] = f'127.0.0.1:{self.rest_port}' else: self.rest_port = self.file['restlisten'].split(':')[-1] if self.file['listen'] is None: if self.network == TESTNET: self.node_port = get_port(LND_DEFAULT_PEER_PORT + 1) else: self.node_port = get_port(LND_DEFAULT_PEER_PORT) self.file['listen'] = f'127.0.0.1:{self.node_port}' else: self.node_port = self.file['listen'].split(':')[-1] if self.file['rpclisten'] is None: if self.network == TESTNET: self.grpc_port = get_port(LND_DEFAULT_GRPC_PORT + 1) else: self.grpc_port = get_port(LND_DEFAULT_GRPC_PORT) self.file['rpclisten'] = f'0.0.0.0:{self.grpc_port}' else: self.grpc_port = self.file['rpclisten'].split(':')[-1] if self.file['tlsextraip'] is None: self.tlsextraip = socket.gethostbyname(socket.gethostname()) self.file['tlsextraip'] = f'{self.tlsextraip}' else: self.tlsextraip = self.file['tlsextraip'].split('=')[-1]
def test_assign_op(self, configuration_file: ConfigurationFile): configuration_file['key'] = 'value' new_object = ConfigurationFile(configuration_file.path, ' ') with open(new_object.path, 'r') as f: text = f.read() assert 'key=value' in text new_object['key'] = 'value' with open(new_object.path, 'r') as f: text = f.read() assert 'key=value' not in text assert 'key value' in text
def __init__(self, network: str, configuration_file_path: str, bitcoin: Bitcoin): self.network = network self.bitcoin = bitcoin self.file = ConfigurationFile(configuration_file_path) self.software = LndSoftware() self.lnddir = LND_DIR_PATH[OPERATING_SYSTEM] if not os.path.exists(self.lnddir): os.mkdir(self.lnddir) self.rest_port = get_port(8080) self.node_port = get_port(9735) self.grpc_port = get_port(10009)
def __init__(self, configuration_file_path: str, bitcoin: Bitcoin): self.running = False self.is_unlocked = False self.bitcoin = bitcoin self.file = ConfigurationFile(configuration_file_path) self.process = self.find_running_node() self.software = LndSoftware() self.lnddir = LND_DIR_PATH[OPERATING_SYSTEM] # Previous versions of the launcher set lnddir in the config file, # but it is not a valid key so this helps old users upgrading if self.file['lnddir'] is not None: self.file['lnddir'] = None if self.file['debuglevel'] is None: self.file['debuglevel'] = 'info' self.file['bitcoin.active'] = True self.file['bitcoin.node'] = 'bitcoind' self.file['bitcoind.rpchost'] = '127.0.0.1' self.file['bitcoind.rpcuser'] = self.bitcoin.file['rpcuser'] self.file['bitcoind.rpcpass'] = self.bitcoin.file['rpcpassword'] self.file['bitcoind.zmqpubrawblock'] = self.bitcoin.file[ 'zmqpubrawblock'] self.file['bitcoind.zmqpubrawtx'] = self.bitcoin.file['zmqpubrawtx'] if self.file['restlisten'] is None: if self.bitcoin.file['testnet']: self.rest_port = get_port(LND_DEFAULT_REST_PORT + 1) else: self.rest_port = get_port(LND_DEFAULT_REST_PORT) self.file['restlisten'] = f'127.0.0.1:{self.rest_port}' else: self.rest_port = self.file['restlisten'].split(':')[-1] if not self.file['rpclisten']: if self.bitcoin.file['testnet']: self.grpc_port = get_port(LND_DEFAULT_GRPC_PORT + 1) else: self.grpc_port = get_port(LND_DEFAULT_GRPC_PORT) self.file['rpclisten'] = f'127.0.0.1:{self.grpc_port}' else: self.grpc_port = int(self.file['rpclisten'].split(':')[-1]) if self.file['color'] is None: self.file['color'] = '#000000' self.macaroon_path = os.path.join(self.lnddir, 'data', 'chain', 'bitcoin', str(self.bitcoin.network))
def __init__(self, network: Network, configuration_file_path: str): self.network = network self.hard_drives = HardDrives() self.software = BitcoinSoftware() self.file = ConfigurationFile(configuration_file_path) self.running = False self.process = None if self.file['server'] is None: self.file['server'] = True if self.file['disablewallet'] is None: self.file['disablewallet'] = True 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['datadir'] is None: self.autoconfigure_datadir() 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: self.file['dbcache'] = 1000 self.check_process()
def __init__(self, network: str, configuration_file_path: str): self.network = network self.hard_drives = HardDrives() self.software = BitcoinSoftware() self.file = ConfigurationFile(configuration_file_path) self.process = self.find_running_node() if self.file.rpcuser is None: self.file.rpcuser = '******' if self.file.rpcpassword is None: self.file.rpcpassword = get_random_password() if self.file.datadir is None: self.autoconfigure_datadir() if self.file.prune is None: self.set_prune(self.hard_drives.should_prune(self.file.datadir, True)) if not self.detect_zmq_ports(): self.zmq_block_port = get_zmq_port() self.zmq_tx_port = get_zmq_port()
def test_getattr(self, configuration_file: ConfigurationFile): configuration_file['test_attribute'] = test_value new_object = ConfigurationFile(configuration_file.path) assert new_object['test_attribute'] == test_value
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()
class Litecoin(object): file: ConfigurationFile hard_drives: HardDrives process: QProcess software: LitecoinSoftware zmq_block_port: int zmq_tx_port: int 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() @property def network(self): if self.file['testnet']: return TESTNET return MAINNET def get_wallet_paths(self): exclude_files = { 'addr.dat', 'banlist.dat', 'fee_estimates.dat', 'mempool.dat', 'peers.dat' } candidate_paths = [] if self.file['testnet']: datadir = os.path.join(self.file['datadir'], 'testnet4') wallet_dir = self.file['test.walletdir'] wallets = self.file['test.wallet'] else: datadir = self.file['datadir'] wallet_dir = self.file['main.walletdir'] wallets = self.file['main.wallet'] for file in os.listdir(datadir): if file not in exclude_files: path = os.path.join(datadir, file) candidate_paths.append(path) default_walletdir = os.path.join(datadir, 'wallets') if os.path.exists(default_walletdir): for file in os.listdir(default_walletdir): if file not in exclude_files: candidate_paths.append( os.path.join(default_walletdir, file)) if wallet_dir is not None: for file in os.listdir(wallet_dir): if file not in exclude_files: candidate_paths += os.path.join( os.path.join(wallet_dir, file)) dat_files = [f for f in candidate_paths if f.endswith('.dat') and not f.startswith('blk')] dat_files = set(dat_files) wallet_paths = set(dat_files - exclude_files) if wallets is not None: if isinstance(wallets, list): for wallet in wallets: wallet_paths.add(wallet) else: wallet_paths.add(wallets) return wallet_paths @property def node_port(self): if self.file['testnet']: custom_port = self.file['test.port'] else: custom_port = self.file['main.port'] if custom_port is not None: return custom_port if self.file['testnet']: return LITECOIN_TESTNET_PEER_PORT return LITECOIN_MAINNET_PEER_PORT @property def rpc_port(self): if self.file['testnet']: custom_port = self.file['test.rpcport'] else: custom_port = self.file['main.rpcport'] if custom_port is not None: return custom_port if self.file['testnet']: return LITECOIN_TESTNET_RPC_PORT return LITECOIN_MAINNET_RPC_PORT def set_prune(self, should_prune: bool = None): if should_prune is None: should_prune = self.hard_drives.should_prune(self.file['datadir'], has_litecoin=True) if should_prune: if self.file['testnet']: prune = TESTNET_PRUNE else: prune = MAINNET_PRUNE self.file['prune'] = prune else: self.file['prune'] = 0 self.file['txindex'] = not should_prune def autoconfigure_datadir(self): default_datadir = LITECOIN_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, has_litecoin=True ) 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.file['datadir'] = default_datadir log.info( 'autoconfigure_datadir', datadir=default_datadir ) return if not self.hard_drives.should_prune(big_drive.mountpoint, False): datadir = os.path.join(big_drive.mountpoint, 'Litecoin') self.file['datadir'] = datadir log.info( 'autoconfigure_datadir', datadir=datadir ) if not os.path.exists(self.file['datadir']): os.mkdir(self.file['datadir']) else: self.file['datadir'] = default_datadir log.info( 'autoconfigure_datadir', datadir=default_datadir ) @property def args(self) -> List[str]: return [f'-conf={self.file.path}'] @property def litecoin_cli(self) -> str: command = [ f'"{self.software.litecoin_cli}"', f'-conf="{self.file.path}"', ] return ' '.join(command) def config_file_changed(self): # Refresh config file self.file.file_watcher.blockSignals(True) self.file.populate_cache() self.file.file_watcher.blockSignals(False) self.zmq_block_port = int(self.file['zmqpubrawblock'].split(':')[-1]) self.zmq_tx_port = int(self.file['zmqpubrawtx'].split(':')[-1]) # Some text editors do not modify the file, they delete and replace the file # Check if file is still in file_watcher list of files, if not add back files_watched = self.file.file_watcher.files() if len(files_watched) == 0: self.file.file_watcher.addPath(self.file.path) @property def restart_required(self): old_config = self.config_snapshot.copy() new_config = self.file.snapshot # First check that both config files are still on the same network old_config_network = 'testnet' in old_config.keys() new_config_network = 'testnet' in new_config.keys() if (old_config_network == new_config_network) and self.running: common_fields = [ 'rpcuser', 'rpcpassword', 'disablewallet', 'datadir', 'disablewallet', 'zmqpubrawblock', 'zmqpubrawtx', 'prune', 'txindex', 'timeout' ] for field in common_fields: # First check if field is found in both configs found_in_old_config = field in old_config.keys() found_in_new_config = field in new_config.keys() if found_in_old_config != found_in_new_config: return True # Now check that values are the same if found_in_old_config: if old_config[field] != new_config[field]: return True if self.file['testnet']: # Only check testnet fields if currently running testnet testnet_fields = [ 'test.rpcport', 'test.port', 'test.wallet', 'test.walletdir' ] for field in testnet_fields: # First check if field is found in both configs found_in_old_config = field in old_config.keys() found_in_new_config = field in new_config.keys() if found_in_old_config != found_in_new_config: return True # Now check that values are the same if found_in_old_config: if old_config[field] != new_config[field]: return True else: # Only check mainnet fields if currently running mainnet mainnet_fields = [ 'rpcport', 'port' ] for field in mainnet_fields: # First check if field is found in both configs found_in_old_config = field in old_config.keys() found_in_new_config = field in new_config.keys() if found_in_old_config != found_in_new_config: return True # Now check that values are the same if found_in_old_config: if old_config[field] != new_config[field]: return True return False elif self.running: # Network has changed and the node is running - Restart is required return True return False
def __init__(self, configuration_file_path: str, litecoin: Litecoin): self.running = False self.is_unlocked = False self.litecoin = litecoin self.file = ConfigurationFile(configuration_file_path) self.software = LndSoftware() self.lnddir = LND_DIR_PATH[OPERATING_SYSTEM] # Previous versions of the launcher set lnddir in the config file, # but it is not a valid key so this helps old users upgrading if self.file['lnddir'] is not None: self.file['lnddir'] = None if self.file['debuglevel'] is None: self.file['debuglevel'] = 'info' self.file['litecoin.active'] = True self.file['litecoin.node'] = 'litecoind' self.file['litecoind.rpchost'] = f'127.0.0.1:{self.litecoin.rpc_port}' self.file['litecoind.rpcuser'] = self.litecoin.file['rpcuser'] self.file['litecoind.rpcpass'] = self.litecoin.file['rpcpassword'] self.file['litecoind.zmqpubrawblock'] = self.litecoin.file[ 'zmqpubrawblock'] self.file['litecoind.zmqpubrawtx'] = self.litecoin.file['zmqpubrawtx'] if self.file['restlisten'] is None: if self.litecoin.file['testnet']: self.rest_port = get_port(LND_DEFAULT_REST_PORT + 1) else: self.rest_port = get_port(LND_DEFAULT_REST_PORT) self.file['restlisten'] = f'127.0.0.1:{self.rest_port}' else: self.rest_port = self.file['restlisten'].split(':')[-1] if not self.file['rpclisten']: if self.litecoin.file['testnet']: self.grpc_port = get_port(LND_DEFAULT_GRPC_PORT + 1) else: self.grpc_port = get_port(LND_DEFAULT_GRPC_PORT) self.file['rpclisten'] = f'127.0.0.1:{self.grpc_port}' else: self.grpc_port = int(self.file['rpclisten'].split(':')[-1]) if not self.file['tlsextraip']: self.file['tlsextraip'] = '127.0.0.1' if self.file['color'] is None: self.file['color'] = '#000000' self.macaroon_path = os.path.join( self.lnddir, 'data', 'chain', 'litecoin', str(self.litecoin.network) ) self.config_snapshot = self.file.snapshot.copy() self.file.file_watcher.fileChanged.connect(self.config_file_changed) self.litecoin.file.file_watcher.fileChanged.connect(self.litecoin_config_file_changed) self.process = QProcess() self.process.setProgram(self.software.lnd) self.process.setCurrentReadChannel(0) self.process.setArguments(self.args) self.process.start()
class Lnd(object): litecoin: Litecoin file: ConfigurationFile software: LndSoftware process: QProcess def __init__(self, configuration_file_path: str, litecoin: Litecoin): self.running = False self.is_unlocked = False self.litecoin = litecoin self.file = ConfigurationFile(configuration_file_path) self.software = LndSoftware() self.lnddir = LND_DIR_PATH[OPERATING_SYSTEM] # Previous versions of the launcher set lnddir in the config file, # but it is not a valid key so this helps old users upgrading if self.file['lnddir'] is not None: self.file['lnddir'] = None if self.file['debuglevel'] is None: self.file['debuglevel'] = 'info' self.file['litecoin.active'] = True self.file['litecoin.node'] = 'litecoind' self.file['litecoind.rpchost'] = f'127.0.0.1:{self.litecoin.rpc_port}' self.file['litecoind.rpcuser'] = self.litecoin.file['rpcuser'] self.file['litecoind.rpcpass'] = self.litecoin.file['rpcpassword'] self.file['litecoind.zmqpubrawblock'] = self.litecoin.file[ 'zmqpubrawblock'] self.file['litecoind.zmqpubrawtx'] = self.litecoin.file['zmqpubrawtx'] if self.file['restlisten'] is None: if self.litecoin.file['testnet']: self.rest_port = get_port(LND_DEFAULT_REST_PORT + 1) else: self.rest_port = get_port(LND_DEFAULT_REST_PORT) self.file['restlisten'] = f'127.0.0.1:{self.rest_port}' else: self.rest_port = self.file['restlisten'].split(':')[-1] if not self.file['rpclisten']: if self.litecoin.file['testnet']: self.grpc_port = get_port(LND_DEFAULT_GRPC_PORT + 1) else: self.grpc_port = get_port(LND_DEFAULT_GRPC_PORT) self.file['rpclisten'] = f'127.0.0.1:{self.grpc_port}' else: self.grpc_port = int(self.file['rpclisten'].split(':')[-1]) if not self.file['tlsextraip']: self.file['tlsextraip'] = '127.0.0.1' if self.file['color'] is None: self.file['color'] = '#000000' self.macaroon_path = os.path.join( self.lnddir, 'data', 'chain', 'litecoin', str(self.litecoin.network) ) self.config_snapshot = self.file.snapshot.copy() self.file.file_watcher.fileChanged.connect(self.config_file_changed) self.litecoin.file.file_watcher.fileChanged.connect(self.litecoin_config_file_changed) self.process = QProcess() self.process.setProgram(self.software.lnd) self.process.setCurrentReadChannel(0) self.process.setArguments(self.args) self.process.start() @property def args(self): if IS_WINDOWS: arg_list = [ f'--configfile={self.file.path}', ] else: arg_list = [ f'--configfile="{self.file.path}"', ] if self.litecoin.file['testnet']: arg_list += [ '--litecoin.testnet' ] else: arg_list += [ '--litecoin.mainnet' ] return arg_list @property def node_port(self) -> str: if self.file['listen'] is None: if self.litecoin.file['testnet']: port = get_port(LND_DEFAULT_PEER_PORT + 1) else: port = get_port(LND_DEFAULT_PEER_PORT) self.file['listen'] = f'127.0.0.1:{port}' else: if not isinstance(self.file['listen'], list): port = self.file['listen'].split(':')[-1] else: port = self.file['listen'][0].split(':')[-1] return port def test_tls_cert(self): context = ssl.create_default_context() context.load_verify_locations(cafile=self.tls_cert_path) conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname='127.0.0.1') conn.connect(('127.0.0.1', int(self.rest_port))) cert = conn.getpeercert() return cert @property def admin_macaroon_path(self) -> str: path = os.path.join(self.macaroon_path, 'admin.macaroon') return path @property def wallet_path(self) -> str: wallet_path = os.path.join(self.macaroon_path, 'wallet.db') return wallet_path @property def has_wallet(self) -> bool: return os.path.isfile(self.wallet_path) @property def tls_cert_path(self) -> str: tls_cert_path = os.path.join(self.lnddir, 'tls.cert') return tls_cert_path def lncli_arguments(self) -> List[str]: args = [] if self.grpc_port != LND_DEFAULT_GRPC_PORT: args.append(f'--rpcserver=127.0.0.1:{self.grpc_port}') if self.litecoin.file['testnet']: args.append(f'--network={self.litecoin.network}') if self.lnddir != LND_DIR_PATH[OPERATING_SYSTEM]: args.append(f'''--lnddir="{self.lnddir}"''') args.append(f'--macaroonpath="{self.macaroon_path}"') args.append(f'--tlscertpath="{self.tls_cert_path}"') return args @property def lncli(self) -> str: base_command = [ f'"{self.software.lncli}"', ] base_command += self.lncli_arguments() return ' '.join(base_command) @property def rest_url(self) -> str: return f'https://127.0.0.1:{self.rest_port}' @property def grpc_url(self) -> str: return f'127.0.0.1:{self.grpc_port}' def config_file_changed(self): # Refresh config file self.file.file_watcher.blockSignals(True) self.file.populate_cache() self.file.file_watcher.blockSignals(False) self.rest_port = int(self.file['restlisten'].split(':')[-1]) self.grpc_port = int(self.file['rpclisten'].split(':')[-1]) # Some text editors do not modify the file, they delete and replace the file # Check if file is still in file_watcher list of files, if not add back files_watched = self.file.file_watcher.files() if len(files_watched) == 0: self.file.file_watcher.addPath(self.file.path) def litecoin_config_file_changed(self): # Refresh config file self.file.file_watcher.blockSignals(True) self.file.populate_cache() self.file.file_watcher.blockSignals(False) self.file['litecoind.rpchost'] = f'127.0.0.1:{self.litecoin.rpc_port}' self.file['litecoind.rpcuser'] = self.litecoin.file['rpcuser'] self.file['litecoind.rpcpass'] = self.litecoin.file['rpcpassword'] self.file['litecoind.zmqpubrawblock'] = self.litecoin.file['zmqpubrawblock'] self.file['litecoind.zmqpubrawtx'] = self.litecoin.file['zmqpubrawtx'] @property def restart_required(self): if self.running: # Did litecoin details change if self.litecoin.restart_required: return True and self.running old_config = self.config_snapshot.copy() new_config = self.file.snapshot fields = [ 'restlisten', 'listen', 'rpclisten' ] for field in fields: # First check if field is found in both configs found_in_old_config = field in old_config.keys() found_in_new_config = field in new_config.keys() if found_in_old_config != found_in_new_config: return True # Now check that values are the same if found_in_old_config: if old_config[field] != new_config[field]: return True return False
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 configuration_file(): with NamedTemporaryFile(suffix='.conf', delete=True) as f: name = f.name configuration_file = ConfigurationFile(name) return configuration_file
def test_setattr(self, configuration_file: ConfigurationFile): configuration_file.test_attribute = test_value with open(configuration_file.path, 'r') as f: text = f.read() assert test_value in text
def test_getattr_bool(self, configuration_file: ConfigurationFile): configuration_file['test_bool_true'] = True configuration_file['test_bool_false'] = False new_object = ConfigurationFile(configuration_file.path) assert new_object['test_bool_true'] assert not new_object['test_bool_false']