mirror of
https://github.com/basicswap/basicswap.git
synced 2025-05-04 20:02:30 +00:00
commit
5270c7da0b
10 changed files with 313 additions and 276 deletions
basicswap
tests/basicswap
|
@ -5,17 +5,18 @@
|
|||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
import os
|
||||
import time
|
||||
import shlex
|
||||
import socks
|
||||
import random
|
||||
import socket
|
||||
import urllib
|
||||
import logging
|
||||
import threading
|
||||
import traceback
|
||||
import os
|
||||
import random
|
||||
import shlex
|
||||
import socket
|
||||
import socks
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
import urllib
|
||||
|
||||
from sockshandler import SocksiPyHandler
|
||||
|
||||
|
@ -42,9 +43,9 @@ def getaddrinfo_tor(*args):
|
|||
|
||||
|
||||
class BaseApp(DBMethods):
|
||||
def __init__(self, fp, data_dir, settings, chain, log_name="BasicSwap"):
|
||||
def __init__(self, data_dir, settings, chain, log_name="BasicSwap"):
|
||||
self.fp = None
|
||||
self.log_name = log_name
|
||||
self.fp = fp
|
||||
self.fail_code = 0
|
||||
self.mock_time_offset = 0
|
||||
|
||||
|
@ -71,24 +72,33 @@ class BaseApp(DBMethods):
|
|||
self.default_socket_timeout = socket.getdefaulttimeout()
|
||||
self.default_socket_getaddrinfo = socket.getaddrinfo
|
||||
|
||||
def __del__(self):
|
||||
if self.fp:
|
||||
self.fp.close()
|
||||
|
||||
def stopRunning(self, with_code=0):
|
||||
self.fail_code = with_code
|
||||
with self.mxDB:
|
||||
self.chainstate_delay_event.set()
|
||||
self.delay_event.set()
|
||||
|
||||
def openLogFile(self):
|
||||
self.fp = open(os.path.join(self.data_dir, "basicswap.log"), "a")
|
||||
|
||||
def prepareLogging(self):
|
||||
logging.setLoggerClass(BSXLogger)
|
||||
self.log = logging.getLogger(self.log_name)
|
||||
self.log.propagate = False
|
||||
|
||||
self.openLogFile()
|
||||
|
||||
# Remove any existing handlers
|
||||
self.log.handlers = []
|
||||
|
||||
formatter = logging.Formatter(
|
||||
"%(asctime)s %(levelname)s : %(message)s", "%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
stream_stdout = logging.StreamHandler()
|
||||
stream_stdout = logging.StreamHandler(sys.stdout)
|
||||
if self.log_name != "BasicSwap":
|
||||
stream_stdout.setFormatter(
|
||||
logging.Formatter(
|
||||
|
@ -98,6 +108,7 @@ class BaseApp(DBMethods):
|
|||
)
|
||||
else:
|
||||
stream_stdout.setFormatter(formatter)
|
||||
self.log_formatter = formatter
|
||||
stream_fp = logging.StreamHandler(self.fp)
|
||||
stream_fp.setFormatter(formatter)
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import concurrent.futures
|
|||
import copy
|
||||
import datetime as dt
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import secrets
|
||||
|
@ -281,14 +282,13 @@ class BasicSwap(BaseApp):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
fp,
|
||||
data_dir,
|
||||
settings,
|
||||
chain,
|
||||
log_name="BasicSwap",
|
||||
transient_instance=False,
|
||||
):
|
||||
super().__init__(fp, data_dir, settings, chain, log_name)
|
||||
super().__init__(data_dir, settings, chain, log_name)
|
||||
|
||||
v = __version__.split(".")
|
||||
self._version = struct.pack(">HHH", int(v[0]), int(v[1]), int(v[2]))
|
||||
|
@ -352,6 +352,13 @@ class BasicSwap(BaseApp):
|
|||
self._expire_db_records_after = self.get_int_setting(
|
||||
"expire_db_records_after", 7 * 86400, 0, 31 * 86400
|
||||
) # Seconds
|
||||
self._max_logfile_bytes = self.settings.get(
|
||||
"max_logfile_size", 100
|
||||
) # In MB 0 to disable truncation
|
||||
if self._max_logfile_bytes > 0:
|
||||
self._max_logfile_bytes *= 1024 * 1024
|
||||
self._max_logfiles = self.get_int_setting("max_logfiles", 10, 1, 100)
|
||||
|
||||
self._notifications_cache = {}
|
||||
self._is_encrypted = None
|
||||
self._is_locked = None
|
||||
|
@ -9724,6 +9731,51 @@ class BasicSwap(BaseApp):
|
|||
self.checkAcceptedBids()
|
||||
self._last_checked_expired = now
|
||||
|
||||
if self._max_logfile_bytes > 0:
|
||||
logfile_size: int = self.fp.tell()
|
||||
self.log.debug(f"Log file bytes: {logfile_size}.")
|
||||
if logfile_size > self._max_logfile_bytes:
|
||||
for i, log_handler in enumerate(self.log.handlers):
|
||||
stream_name = getattr(log_handler.stream, "name", "")
|
||||
if stream_name.endswith(".log"):
|
||||
del self.log.handlers[i]
|
||||
break
|
||||
|
||||
self.fp.close()
|
||||
log_path = os.path.join(self.data_dir, "basicswap.log")
|
||||
if self._max_logfiles == 1:
|
||||
os.remove(log_path)
|
||||
else:
|
||||
last_log = os.path.join(
|
||||
self.data_dir,
|
||||
f"basicswap_{self._max_logfiles - 1:0>2}.log",
|
||||
)
|
||||
if os.path.exists(last_log):
|
||||
os.remove(last_log)
|
||||
|
||||
for i in range(self._max_logfiles - 2, 0, -1):
|
||||
path_from = os.path.join(
|
||||
self.data_dir, f"basicswap_{i:0>2}.log"
|
||||
)
|
||||
path_to = os.path.join(
|
||||
self.data_dir, f"basicswap_{i + 1:0>2}.log"
|
||||
)
|
||||
if os.path.exists(path_from):
|
||||
os.rename(path_from, path_to)
|
||||
|
||||
log_path = os.path.join(self.data_dir, "basicswap.log")
|
||||
os.rename(
|
||||
log_path,
|
||||
os.path.join(self.data_dir, "basicswap_01.log"),
|
||||
)
|
||||
|
||||
self.openLogFile()
|
||||
|
||||
stream_fp = logging.StreamHandler(self.fp)
|
||||
stream_fp.setFormatter(self.log_formatter)
|
||||
self.log.addHandler(stream_fp)
|
||||
self.log.info("Log file rotated.")
|
||||
|
||||
if now - self._last_checked_actions >= self.check_actions_seconds:
|
||||
self.checkQueuedActions()
|
||||
self._last_checked_actions = now
|
||||
|
|
|
@ -1733,11 +1733,8 @@ def test_particl_encryption(data_dir, settings, chain, use_tor_proxy):
|
|||
swap_client = None
|
||||
daemons = []
|
||||
daemon_args = ["-noconnect", "-nodnsseed", "-nofindpeers", "-nostaking"]
|
||||
with open(os.path.join(data_dir, "basicswap.log"), "a") as fp:
|
||||
try:
|
||||
swap_client = BasicSwap(
|
||||
fp, data_dir, settings, chain, transient_instance=True
|
||||
)
|
||||
swap_client = BasicSwap(data_dir, settings, chain, transient_instance=True)
|
||||
if not swap_client.use_tor_proxy:
|
||||
# Cannot set -bind or -whitebind together with -listen=0
|
||||
daemon_args.append("-nolisten")
|
||||
|
@ -1793,11 +1790,8 @@ def initialise_wallets(
|
|||
|
||||
coins_failed_to_initialise = []
|
||||
|
||||
with open(os.path.join(data_dir, "basicswap.log"), "a") as fp:
|
||||
try:
|
||||
swap_client = BasicSwap(
|
||||
fp, data_dir, settings, chain, transient_instance=True
|
||||
)
|
||||
swap_client = BasicSwap(data_dir, settings, chain, transient_instance=True)
|
||||
if not swap_client.use_tor_proxy:
|
||||
# Cannot set -bind or -whitebind together with -listen=0
|
||||
daemon_args.append("-nolisten")
|
||||
|
@ -1822,9 +1816,7 @@ def initialise_wallets(
|
|||
if c == Coins.XMR:
|
||||
if coin_settings["manage_wallet_daemon"]:
|
||||
filename = (
|
||||
coin_name
|
||||
+ "-wallet-rpc"
|
||||
+ (".exe" if os.name == "nt" else "")
|
||||
coin_name + "-wallet-rpc" + (".exe" if os.name == "nt" else "")
|
||||
)
|
||||
filename: str = getWalletBinName(
|
||||
c, coin_settings, coin_name + "-wallet-rpc"
|
||||
|
@ -1852,9 +1844,7 @@ def initialise_wallets(
|
|||
pass
|
||||
else:
|
||||
if coin_settings["manage_daemon"]:
|
||||
filename: str = getCoreBinName(
|
||||
c, coin_settings, coin_name + "d"
|
||||
)
|
||||
filename: str = getCoreBinName(c, coin_settings, coin_name + "d")
|
||||
coin_args = (
|
||||
["-nofindpeers", "-nostaking"] if c == Coins.PART else []
|
||||
)
|
||||
|
@ -1916,9 +1906,7 @@ def initialise_wallets(
|
|||
if c in (Coins.BTC, Coins.LTC, Coins.DOGE, Coins.DASH):
|
||||
# wallet_name, disable_private_keys, blank, passphrase, avoid_reuse, descriptors
|
||||
|
||||
use_descriptors = coin_settings.get(
|
||||
"use_descriptors", False
|
||||
)
|
||||
use_descriptors = coin_settings.get("use_descriptors", False)
|
||||
swap_client.callcoinrpc(
|
||||
c,
|
||||
"createwallet",
|
||||
|
@ -1992,9 +1980,7 @@ def initialise_wallets(
|
|||
coins_failed_to_initialise.append((c, e))
|
||||
if WALLET_ENCRYPTION_PWD != "" and c not in coins_to_create_wallets_for:
|
||||
try:
|
||||
swap_client.ci(c).changeWalletPassword(
|
||||
"", WALLET_ENCRYPTION_PWD
|
||||
)
|
||||
swap_client.ci(c).changeWalletPassword("", WALLET_ENCRYPTION_PWD)
|
||||
except Exception as e: # noqa: F841
|
||||
logger.warning(f"changeWalletPassword failed for {coin_name}.")
|
||||
|
||||
|
|
|
@ -272,8 +272,8 @@ def getCoreBinArgs(coin_id: int, coin_settings, prepare=False, use_tor_proxy=Fal
|
|||
|
||||
|
||||
def runClient(
|
||||
fp, data_dir: str, chain: str, start_only_coins: bool, log_prefix: str = "BasicSwap"
|
||||
):
|
||||
data_dir: str, chain: str, start_only_coins: bool, log_prefix: str = "BasicSwap"
|
||||
) -> int:
|
||||
global swap_client, logger
|
||||
daemons = []
|
||||
pids = []
|
||||
|
@ -298,7 +298,7 @@ def runClient(
|
|||
with open(settings_path) as fs:
|
||||
settings = json.load(fs)
|
||||
|
||||
swap_client = BasicSwap(fp, data_dir, settings, chain, log_name=log_prefix)
|
||||
swap_client = BasicSwap(data_dir, settings, chain, log_name=log_prefix)
|
||||
logger = swap_client.log
|
||||
|
||||
if os.path.exists(pids_path):
|
||||
|
@ -482,7 +482,6 @@ def runClient(
|
|||
else cfg.DEFAULT_ALLOW_CORS
|
||||
)
|
||||
thread_http = HttpThread(
|
||||
fp,
|
||||
settings["htmlhost"],
|
||||
settings["htmlport"],
|
||||
allow_cors,
|
||||
|
@ -548,6 +547,9 @@ def runClient(
|
|||
except Exception as e:
|
||||
swap_client.log.error(f"Error: {e}")
|
||||
|
||||
fail_code: int = swap_client.fail_code
|
||||
del swap_client
|
||||
|
||||
if os.path.exists(pids_path):
|
||||
with open(pids_path) as fd:
|
||||
lines = fd.read().split("\n")
|
||||
|
@ -561,6 +563,8 @@ def runClient(
|
|||
with open(pids_path, "w") as fd:
|
||||
fd.write(still_running)
|
||||
|
||||
return fail_code
|
||||
|
||||
|
||||
def printVersion():
|
||||
logger.info(
|
||||
|
@ -642,14 +646,11 @@ def main():
|
|||
if not os.path.exists(data_dir):
|
||||
os.makedirs(data_dir)
|
||||
|
||||
with open(os.path.join(data_dir, "basicswap.log"), "a") as fp:
|
||||
logger.info(
|
||||
os.path.basename(sys.argv[0]) + ", version: " + __version__ + "\n\n"
|
||||
)
|
||||
runClient(fp, data_dir, chain, start_only_coins, log_prefix)
|
||||
logger.info(os.path.basename(sys.argv[0]) + ", version: " + __version__ + "\n\n")
|
||||
fail_code = runClient(data_dir, chain, start_only_coins, log_prefix)
|
||||
|
||||
print("Done.")
|
||||
return swap_client.fail_code if swap_client is not None else 0
|
||||
return fail_code
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -637,11 +637,10 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||
|
||||
|
||||
class HttpThread(threading.Thread, HTTPServer):
|
||||
def __init__(self, fp, host_name, port_no, allow_cors, swap_client):
|
||||
def __init__(self, host_name, port_no, allow_cors, swap_client):
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
self.stop_event = threading.Event()
|
||||
self.fp = fp
|
||||
self.host_name = host_name
|
||||
self.port_no = port_no
|
||||
self.allow_cors = allow_cors
|
||||
|
|
|
@ -408,9 +408,8 @@ class Test(unittest.TestCase):
|
|||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
with open(settings_path) as fs:
|
||||
settings = json.load(fs)
|
||||
fp = open(os.path.join(basicswap_dir, "basicswap.log"), "w")
|
||||
sc = BasicSwap(
|
||||
fp, basicswap_dir, settings, "regtest", log_name="BasicSwap{}".format(i)
|
||||
basicswap_dir, settings, "regtest", log_name="BasicSwap{}".format(i)
|
||||
)
|
||||
cls.swap_clients.append(sc)
|
||||
sc.setDaemonPID(Coins.BTC, cls.daemons[0].handle.pid)
|
||||
|
@ -423,7 +422,7 @@ class Test(unittest.TestCase):
|
|||
|
||||
sc.start()
|
||||
|
||||
t = HttpThread(sc.fp, TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
||||
t = HttpThread(TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
||||
cls.http_threads.append(t)
|
||||
t.start()
|
||||
|
||||
|
@ -484,7 +483,6 @@ class Test(unittest.TestCase):
|
|||
t.join()
|
||||
for c in cls.swap_clients:
|
||||
c.finalise()
|
||||
c.fp.close()
|
||||
|
||||
stopDaemons(cls.daemons)
|
||||
|
||||
|
|
|
@ -325,9 +325,7 @@ class Test(unittest.TestCase):
|
|||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
with open(settings_path) as fs:
|
||||
settings = json.load(fs)
|
||||
fp = open(os.path.join(basicswap_dir, "basicswap.log"), "w")
|
||||
sc = BasicSwap(
|
||||
fp,
|
||||
basicswap_dir,
|
||||
settings,
|
||||
"regtest",
|
||||
|
@ -338,7 +336,7 @@ class Test(unittest.TestCase):
|
|||
sc.setDaemonPID(Coins.PART, cls.part_daemons[i].handle.pid)
|
||||
sc.start()
|
||||
|
||||
t = HttpThread(sc.fp, TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
||||
t = HttpThread(TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
||||
cls.http_threads.append(t)
|
||||
t.start()
|
||||
|
||||
|
@ -397,7 +395,6 @@ class Test(unittest.TestCase):
|
|||
t.join()
|
||||
for c in cls.swap_clients:
|
||||
c.finalise()
|
||||
c.fp.close()
|
||||
|
||||
stopDaemons(cls.part_daemons)
|
||||
stopDaemons(cls.btc_daemons)
|
||||
|
|
|
@ -365,9 +365,8 @@ class Test(unittest.TestCase):
|
|||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
with open(settings_path) as fs:
|
||||
settings = json.load(fs)
|
||||
fp = open(os.path.join(basicswap_dir, "basicswap.log"), "w")
|
||||
sc = BasicSwap(
|
||||
fp, basicswap_dir, settings, "regtest", log_name="BasicSwap{}".format(i)
|
||||
basicswap_dir, settings, "regtest", log_name="BasicSwap{}".format(i)
|
||||
)
|
||||
cls.swap_clients.append(sc)
|
||||
|
||||
|
@ -376,7 +375,7 @@ class Test(unittest.TestCase):
|
|||
sc.setDaemonPID(Coins.PART, cls.daemons[2 + i].handle.pid)
|
||||
sc.start()
|
||||
|
||||
t = HttpThread(sc.fp, TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
||||
t = HttpThread(TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
||||
cls.http_threads.append(t)
|
||||
t.start()
|
||||
|
||||
|
@ -437,7 +436,6 @@ class Test(unittest.TestCase):
|
|||
t.join()
|
||||
for c in cls.swap_clients:
|
||||
c.finalise()
|
||||
c.fp.close()
|
||||
|
||||
stopDaemons(cls.daemons)
|
||||
cls.http_threads.clear()
|
||||
|
|
|
@ -414,9 +414,8 @@ class Test(unittest.TestCase):
|
|||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
with open(settings_path) as fs:
|
||||
settings = json.load(fs)
|
||||
fp = open(os.path.join(basicswap_dir, "basicswap.log"), "w")
|
||||
sc = BasicSwap(
|
||||
fp, basicswap_dir, settings, "regtest", log_name="BasicSwap{}".format(i)
|
||||
basicswap_dir, settings, "regtest", log_name="BasicSwap{}".format(i)
|
||||
)
|
||||
cls.swap_clients.append(sc)
|
||||
sc.setDaemonPID(Coins.BTC, cls.daemons[0].handle.pid)
|
||||
|
@ -424,7 +423,7 @@ class Test(unittest.TestCase):
|
|||
sc.setDaemonPID(Coins.PART, cls.daemons[2 + i].handle.pid)
|
||||
sc.start()
|
||||
|
||||
t = HttpThread(sc.fp, TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
||||
t = HttpThread(TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
||||
cls.http_threads.append(t)
|
||||
t.start()
|
||||
|
||||
|
@ -482,7 +481,6 @@ class Test(unittest.TestCase):
|
|||
t.join()
|
||||
for c in cls.swap_clients:
|
||||
c.finalise()
|
||||
c.fp.close()
|
||||
|
||||
stopDaemons(cls.daemons)
|
||||
cls.http_threads.clear()
|
||||
|
|
|
@ -654,9 +654,7 @@ class BaseTest(unittest.TestCase):
|
|||
if cls.restore_instance and i == 1:
|
||||
cls.network_key = settings["network_key"]
|
||||
cls.network_pubkey = settings["network_pubkey"]
|
||||
fp = open(os.path.join(basicswap_dir, "basicswap.log"), "w")
|
||||
sc = BasicSwap(
|
||||
fp,
|
||||
basicswap_dir,
|
||||
settings,
|
||||
"regtest",
|
||||
|
@ -684,7 +682,7 @@ class BaseTest(unittest.TestCase):
|
|||
# Import a random seed to keep the existing test behaviour. BTC core rescans even with timestamp: now.
|
||||
sc.ci(Coins.BTC).initialiseWallet(random.randbytes(32))
|
||||
|
||||
t = HttpThread(sc.fp, TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
||||
t = HttpThread(TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
||||
cls.http_threads.append(t)
|
||||
t.start()
|
||||
# Set future block rewards to nowhere (a random address), so wallet amounts stay constant
|
||||
|
@ -952,7 +950,6 @@ class BaseTest(unittest.TestCase):
|
|||
logging.info("Stopping swap clients")
|
||||
for c in cls.swap_clients:
|
||||
c.finalise()
|
||||
c.fp.close()
|
||||
|
||||
logging.info("Stopping coin nodes")
|
||||
stopDaemons(cls.xmr_daemons)
|
||||
|
|
Loading…
Reference in a new issue