own timeout

This commit is contained in:
callebtc
2022-10-31 11:01:41 +01:00
parent fec209eb34
commit 16815a283e
5 changed files with 78 additions and 30 deletions

41
cashu/tor/timeout.py Executable file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/env python
import os
import signal
import subprocess
import sys
import time
def main():
assert len(sys.argv) > 2, "Usage: timeout.py [seconds] [command...]"
cmd = " ".join(sys.argv[2:])
timeout = int(sys.argv[1])
start_time = time.time()
assert timeout > 0, "timeout (in seconds) must be a positive integer."
pro = subprocess.Popen(cmd, shell=True)
while time.time() < start_time + timeout:
time.sleep(1)
# check if process is still running
try:
os.getpgid(pro.pid)
except ProcessLookupError:
break
# terminate process
try:
os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
except ProcessLookupError:
return
# kill process
time.sleep(1.0)
try:
os.killpg(os.getpgid(pro.pid), signal.SIGKILL)
except ProcessLookupError:
return
if __name__ == "__main__":
main()

View File

@@ -9,41 +9,46 @@ from loguru import logger
class TorProxy:
def __init__(self, keep_alive=False, dont_start=False):
def __init__(self, timeout=False):
self.base_path = pathlib.Path(__file__).parent.resolve()
self.platform = platform.system()
self.keep_alive = 60 * 60 if keep_alive else 0 # seconds
self.timeout = 60 * 60 if timeout else 0 # seconds
self.tor_proc = None
self.pid_file = os.path.join(self.base_path, "tor.pid")
self.tor_pid = None
self.startup_finished = True
self.tor_running = self.is_running()
logger.debug(f"Tor running: {self.tor_running}")
logger.debug(
f"Tor port open: {self.is_port_open()}",
)
logger.debug(f"Tor binary path: {self.tor_path()}")
logger.debug(f"Tor config path: {self.tor_config_path()}")
logger.debug(f"Tor PID in tor.pid: {self.read_pid()}")
logger.debug(f"Tor PID running: {self.signal_pid(self.read_pid())}")
if not self.tor_running and not dont_start:
self.run_daemon()
@classmethod
def check_platform(cls):
if platform.system() == "Linux":
if platform.machine() != "x86_64":
logger.debug("Builtin Tor not supported on this platform.")
return False
return True
def run_daemon(self):
if not self.check_platform():
def log_status(self):
logger.debug(f"Tor binary path: {self.tor_path()}")
logger.debug(f"Tor config path: {self.tor_config_path()}")
logger.debug(f"Tor running: {self.tor_running}")
logger.debug(
f"Tor port open: {self.is_port_open()}",
)
logger.debug(f"Tor PID in tor.pid: {self.read_pid()}")
logger.debug(f"Tor PID running: {self.signal_pid(self.read_pid())}")
def run_daemon(self, verbose=False):
if not self.check_platform() or self.tor_running:
return
self.log_status()
logger.debug("Starting Tor")
cmd = [f"{self.tor_path()}", "--defaults-torrc", f"{self.tor_config_path()}"]
if self.keep_alive and platform.system() != "Windows":
cmd = ["timeout", f"{self.keep_alive}"] + cmd
if self.timeout:
logger.debug(f"Starting tor with timeout {self.timeout}s")
cmd = [
os.path.join(self.base_path, "timeout.py"),
f"{self.timeout}",
] + cmd
env = dict(os.environ)
if platform.system() == "Linux":
env["LD_LIBRARY_PATH"] = os.path.dirname(self.tor_path())
@@ -62,6 +67,8 @@ class TorProxy:
with open(self.pid_file, "w", encoding="utf-8") as f:
f.write(str(self.tor_proc.pid))
self.wait_until_startup(verbose=verbose)
def stop_daemon(self, pid=None):
pid = pid or self.tor_proc.pid if self.tor_proc else None
if self.tor_proc and pid:
@@ -92,13 +99,13 @@ class TorProxy:
def is_running(self):
# our tor proxy running from a previous session
if self.signal_pid(self.read_pid()):
logger.debug("Tor proxy already running.")
# logger.debug("Tor proxy already running.")
return True
# another tor proxy is running
if self.is_port_open():
logger.debug(
"Another Tor instance seems to be already running on port 9050."
)
# logger.debug(
# "Another Tor instance seems to be already running on port 9050."
# )
return True
# current attached process running
return self.tor_proc and self.tor_proc.poll() is None
@@ -165,8 +172,8 @@ class TorProxy:
if __name__ == "__main__":
tor = TorProxy()
tor.wait_until_startup(verbose=True)
tor = TorProxy(timeout=True)
tor.run_daemon(verbose=True)
# time.sleep(5)
# logger.debug("Killing Tor")
# tor.stop_daemon()

View File

@@ -72,7 +72,7 @@ def cli(ctx, host: str, walletname: str):
ctx.obj["WALLET_NAME"] = walletname
wallet = Wallet(ctx.obj["HOST"], os.path.join(CASHU_DIR, walletname))
if TOR and not TorProxy(dont_start=True).check_platform():
if TOR and not TorProxy().check_platform():
print(
"WARNING: Your settings say TOR=true but the built-in Tor bundle is not supported on your system. Your IP will be visible to the mint! Please install Tor manually and set TOR=false and SOCKS_HOST=localhost and SOCKS_PORT=9050 in your Cashu config (recommended) or turn off Tor altogether by setting TOR=false (not recommended)."
)

View File

@@ -64,9 +64,9 @@ class LedgerAPI:
s = requests.Session()
s.headers.update({"Client-version": VERSION})
socks_host, socks_port = None, None
if TOR and TorProxy(dont_start=True).check_platform():
self.tor = TorProxy(keep_alive=True)
self.tor.wait_until_startup(verbose=True)
if TOR and TorProxy().check_platform():
self.tor = TorProxy(timeout=True)
self.tor.run_daemon(verbose=True)
socks_host, socks_port = "localhost", 9050
else:
socks_host, socks_port = SOCKS_HOST, SOCKS_PORT

View File

@@ -4,12 +4,12 @@ import requests
from cashu.tor.tor import TorProxy
@pytest.mark.skip
# @pytest.mark.skip
def test_tor_setup():
s = requests.Session()
tor = TorProxy(keep_alive=False)
tor.wait_until_startup()
tor = TorProxy(timeout=False)
tor.run_daemon()
socks_host, socks_port = "localhost", 9050
proxies = {