Browse Source

Add support to build and autostart local Tor instance in jmvenv

master
Kristaps Kaupe 4 years ago
parent
commit
7a88781648
No known key found for this signature in database
GPG Key ID: 33E472FE870C7E5D
  1. 82
      install.sh
  2. 3
      jmclient/jmclient/__init__.py
  3. 32
      jmclient/jmclient/configure.py
  4. 4
      jmclient/jmclient/yieldgenerator.py
  5. 4
      scripts/joinmarket-qt.py
  6. 3
      scripts/obwatch/ob-watcher.py
  7. 4
      scripts/sendpayment.py

82
install.sh

@ -82,6 +82,28 @@ deps_install ()
fi
}
tor_deps_install ()
{
debian_deps=( \
'libevent-dev' \
'libssl-dev' \
'zlib1g-dev' )
# TODO: darwin_deps
if [[ ${use_os_deps_check} != '1' ]]; then
return 0
elif [[ ${install_os} == 'debian' ]]; then
deb_deps_install "${debian_deps[@]}"
return "$?"
elif [[ ${install_os} == 'darwin' ]]; then
echo "FixMe: Darwin deps not specified. Trying to build."
return 0
else
return 0
fi
}
deb_deps_check ()
{
apt-cache policy ${deb_deps[@]} | grep "Installed.*none"
@ -325,6 +347,49 @@ libsodium_install ()
popd
}
tor_build ()
{
$make uninstall
$make distclean
./configure \
--disable-system-torrc \
--disable-seccomp \
--disable-libscrypt \
--disable-module-relay \
--disable-lzma \
--disable-zstd \
--disable-asciidoc \
--disable-manpage \
--disable-html-manual \
--prefix="${jm_root}"
$make
if ! $make check; then
return 1
fi
}
tor_install ()
{
tor_version='tor-0.4.6.8'
tor_tar="${tor_version}.tar.gz"
tor_sha='15ce1a37b4cc175b07761e00acdcfa2c08f0d23d6c3ab9c97c464bd38cc5476a'
tor_url='https://dist.torproject.org'
if ! dep_get "${tor_tar}" "${tor_sha}" "${tor_url}"; then
return 1
fi
pushd "${tor_version}"
if tor_build; then
$make install
# Create blank tor config, it will default to running socks5 proxy
# at 127.0.0.1:9050 and should be enough for us.
> "${jm_root}/etc/tor/torrc"
else
return 1
fi
popd
}
joinmarket_install ()
{
reqs=( 'base.txt' )
@ -379,6 +444,9 @@ parse_flags ()
echo 'ERROR: "--python" requires a non-empty option argument.'
return 1
;;
--with-local-tor)
build_local_tor='1'
;;
--with-qt)
with_qt='1'
;;
@ -403,6 +471,7 @@ Options:
--disable-secp-check do not run libsecp256k1 tests (default is to run them)
--docker-install system wide install as root for minimal Docker installs
--python, -p python version (only python3 versions are supported)
--with-local-tor build Tor locally and autostart when needed
--with-qt build the Qt GUI
--without-qt don't build the Qt GUI
"
@ -459,6 +528,7 @@ main ()
# flags
develop_build=''
python='python3'
build_local_tor=''
use_os_deps_check='1'
use_secp_check='1'
with_qt=''
@ -495,6 +565,12 @@ main ()
fi
source "${jm_root}/bin/activate"
fi
if [[ ${build_local_tor} == "1" ]]; then
if ! tor_deps_install; then
echo "Tor dependencies could not be installed. Exiting."
return 1
fi
fi
mkdir -p "deps/cache"
pushd deps
if ! libsecp256k1_install; then
@ -509,6 +585,12 @@ main ()
echo "Libsodium was not built. Exiting."
return 1
fi
if [[ ${build_local_tor} == "1" ]]; then
if ! tor_install; then
echo "Building local Tor was requested, but not built. Exiting."
return 1
fi
fi
popd
if ! joinmarket_install; then
echo "Joinmarket was not installed. Exiting."

3
jmclient/jmclient/__init__.py

@ -26,7 +26,8 @@ from .configure import (load_test_config, process_shutdown,
load_program_config, jm_single, get_network, update_persist_config,
validate_address, is_burn_destination, get_irc_mchannels,
get_blockchain_interface_instance, set_config, is_segwit_mode,
is_native_segwit_mode, JMPluginService, get_interest_rate, get_bondless_makers_allowance)
is_native_segwit_mode, JMPluginService, get_interest_rate,
get_bondless_makers_allowance, check_and_start_tor)
from .blockchaininterface import (BlockchainInterface,
RegtestBitcoinCoreInterface, BitcoinCoreInterface)
from .snicker_receiver import SNICKERError, SNICKERReceiver

32
jmclient/jmclient/configure.py

@ -3,7 +3,11 @@ import io
import logging
import os
import re
import socket
import sys
import subprocess
import atexit
from signal import SIGINT
from configparser import ConfigParser, NoOptionError
@ -749,6 +753,34 @@ def load_program_config(config_path="", bs=None, plugin_services=[]):
os.makedirs(plogsdir)
p.set_log_dir(plogsdir)
def gracefully_kill_subprocess(p):
# See https://stackoverflow.com/questions/43274476/is-there-a-way-to-check-if-a-subprocess-is-still-running
if p.poll() is None:
p.send_signal(SIGINT)
def check_and_start_tor():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex(("127.0.0.1", 9050))
sock.close()
if result == 0:
return
log.info("Nobody listens on 127.0.0.1:9050, trying to start Tor.")
tor_bin = os.path.join(sys.prefix, "bin", "tor")
if not os.path.exists(tor_bin):
log.info("Can't find our custom tor.")
return
command = [tor_bin, "-f", os.path.join(sys.prefix,
"etc", "tor", "torrc")]
# output messages from tor if loglevel is debug, they might be useful
if global_singleton.config.get("LOGGING", "console_log_level") == "DEBUG":
tor_stdout = sys.stdout
else:
tor_stdout = open(os.devnull, 'w')
tor_subprocess = subprocess.Popen(command, stdout=tor_stdout,
stderr=subprocess.STDOUT, close_fds=True)
atexit.register(gracefully_kill_subprocess, tor_subprocess)
log.debug("Started Tor subprocess with pid " + str(tor_subprocess.pid))
def load_test_config(**kwargs):
if "config_path" not in kwargs:
load_program_config(config_path=".", **kwargs)

4
jmclient/jmclient/yieldgenerator.py

@ -14,7 +14,7 @@ from jmclient import (Maker, jm_single, load_program_config,
JMClientProtocolFactory, start_reactor, calc_cj_fee,
WalletService, add_base_options, SNICKERReceiver,
SNICKERClientProtocolFactory, FidelityBondMixin,
get_interest_rate, fmt_utxo)
get_interest_rate, fmt_utxo, check_and_start_tor)
from .wallet_utils import open_test_wallet_maybe, get_wallet_path
from jmbase.support import EXIT_ARGERROR, EXIT_FAILURE, get_jm_version_str
import jmbitcoin as btc
@ -401,6 +401,8 @@ def ygmain(ygclass, nickserv_password='', gaplimit=6):
load_program_config(config_path=options["datadir"])
check_and_start_tor()
# As per previous note, override non-default command line settings:
for x in ["ordertype", "txfee_contribution", "txfee_contribution_factor",
"cjfee_a", "cjfee_r", "cjfee_factor", "minsize", "size_factor"]:

4
scripts/joinmarket-qt.py

@ -73,7 +73,7 @@ from jmclient import load_program_config, get_network, update_persist_config,\
parse_payjoin_setup, send_payjoin, JMBIP78ReceiverManager, \
detect_script_type, general_custom_change_warning, \
nonwallet_custom_change_warning, sweep_custom_change_warning, EngineError,\
TYPE_P2WPKH
TYPE_P2WPKH, check_and_start_tor
from jmclient.wallet import BaseWallet
from qtsupport import ScheduleWizard, TumbleRestartWizard, config_tips,\
@ -2376,6 +2376,8 @@ if not jm_single().config.get("POLICY", "segwit") == "true":
update_config_for_gui()
check_and_start_tor()
def onTabChange(i):
""" Respond to change of tab.
"""

3
scripts/obwatch/ob-watcher.py

@ -24,7 +24,7 @@ if sys.version_info < (3, 7):
from jmbase.support import EXIT_FAILURE
from jmbase import bintohex
from jmclient import FidelityBondMixin, get_interest_rate
from jmclient import FidelityBondMixin, get_interest_rate, check_and_start_tor
from jmclient.fidelity_bond import FidelityBondProof
import sybil_attack_calculations as sybil
@ -803,6 +803,7 @@ def main():
default=62601)
(options, args) = parser.parse_args()
load_program_config(config_path=options.datadir)
check_and_start_tor()
hostport = (options.host, options.port)
mcs = [ObIRCMessageChannel(c) for c in get_irc_mchannels()]
mcc = MessageChannelCollection(mcs)

4
scripts/sendpayment.py

@ -18,7 +18,7 @@ from jmclient import Taker, load_program_config, get_schedule,\
get_sendpayment_parser, get_max_cj_fee_values, check_regtest, \
parse_payjoin_setup, send_payjoin, general_custom_change_warning, \
nonwallet_custom_change_warning, sweep_custom_change_warning, \
EngineError
EngineError, check_and_start_tor
from twisted.python.log import startLogging
from jmbase.support import get_log, jmprint, \
EXIT_FAILURE, EXIT_ARGERROR
@ -63,6 +63,8 @@ def main():
" wallet, amount, destination address or wallet, bitcoin_uri.")
sys.exit(EXIT_ARGERROR)
check_and_start_tor()
#without schedule file option, use the arguments to create a schedule
#of a single transaction
sweeping = False

Loading…
Cancel
Save