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 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 () deb_deps_check ()
{ {
apt-cache policy ${deb_deps[@]} | grep "Installed.*none" apt-cache policy ${deb_deps[@]} | grep "Installed.*none"
@ -325,6 +347,49 @@ libsodium_install ()
popd 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 () joinmarket_install ()
{ {
reqs=( 'base.txt' ) reqs=( 'base.txt' )
@ -379,6 +444,9 @@ parse_flags ()
echo 'ERROR: "--python" requires a non-empty option argument.' echo 'ERROR: "--python" requires a non-empty option argument.'
return 1 return 1
;; ;;
--with-local-tor)
build_local_tor='1'
;;
--with-qt) --with-qt)
with_qt='1' with_qt='1'
;; ;;
@ -403,6 +471,7 @@ Options:
--disable-secp-check do not run libsecp256k1 tests (default is to run them) --disable-secp-check do not run libsecp256k1 tests (default is to run them)
--docker-install system wide install as root for minimal Docker installs --docker-install system wide install as root for minimal Docker installs
--python, -p python version (only python3 versions are supported) --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 --with-qt build the Qt GUI
--without-qt don't build the Qt GUI --without-qt don't build the Qt GUI
" "
@ -459,6 +528,7 @@ main ()
# flags # flags
develop_build='' develop_build=''
python='python3' python='python3'
build_local_tor=''
use_os_deps_check='1' use_os_deps_check='1'
use_secp_check='1' use_secp_check='1'
with_qt='' with_qt=''
@ -495,6 +565,12 @@ main ()
fi fi
source "${jm_root}/bin/activate" source "${jm_root}/bin/activate"
fi 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" mkdir -p "deps/cache"
pushd deps pushd deps
if ! libsecp256k1_install; then if ! libsecp256k1_install; then
@ -509,6 +585,12 @@ main ()
echo "Libsodium was not built. Exiting." echo "Libsodium was not built. Exiting."
return 1 return 1
fi 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 popd
if ! joinmarket_install; then if ! joinmarket_install; then
echo "Joinmarket was not installed. Exiting." 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, load_program_config, jm_single, get_network, update_persist_config,
validate_address, is_burn_destination, get_irc_mchannels, validate_address, is_burn_destination, get_irc_mchannels,
get_blockchain_interface_instance, set_config, is_segwit_mode, 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, from .blockchaininterface import (BlockchainInterface,
RegtestBitcoinCoreInterface, BitcoinCoreInterface) RegtestBitcoinCoreInterface, BitcoinCoreInterface)
from .snicker_receiver import SNICKERError, SNICKERReceiver from .snicker_receiver import SNICKERError, SNICKERReceiver

32
jmclient/jmclient/configure.py

@ -3,7 +3,11 @@ import io
import logging import logging
import os import os
import re import re
import socket
import sys import sys
import subprocess
import atexit
from signal import SIGINT
from configparser import ConfigParser, NoOptionError from configparser import ConfigParser, NoOptionError
@ -749,6 +753,34 @@ def load_program_config(config_path="", bs=None, plugin_services=[]):
os.makedirs(plogsdir) os.makedirs(plogsdir)
p.set_log_dir(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): def load_test_config(**kwargs):
if "config_path" not in kwargs: if "config_path" not in kwargs:
load_program_config(config_path=".", **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, JMClientProtocolFactory, start_reactor, calc_cj_fee,
WalletService, add_base_options, SNICKERReceiver, WalletService, add_base_options, SNICKERReceiver,
SNICKERClientProtocolFactory, FidelityBondMixin, 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 .wallet_utils import open_test_wallet_maybe, get_wallet_path
from jmbase.support import EXIT_ARGERROR, EXIT_FAILURE, get_jm_version_str from jmbase.support import EXIT_ARGERROR, EXIT_FAILURE, get_jm_version_str
import jmbitcoin as btc import jmbitcoin as btc
@ -401,6 +401,8 @@ def ygmain(ygclass, nickserv_password='', gaplimit=6):
load_program_config(config_path=options["datadir"]) load_program_config(config_path=options["datadir"])
check_and_start_tor()
# As per previous note, override non-default command line settings: # As per previous note, override non-default command line settings:
for x in ["ordertype", "txfee_contribution", "txfee_contribution_factor", for x in ["ordertype", "txfee_contribution", "txfee_contribution_factor",
"cjfee_a", "cjfee_r", "cjfee_factor", "minsize", "size_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, \ parse_payjoin_setup, send_payjoin, JMBIP78ReceiverManager, \
detect_script_type, general_custom_change_warning, \ detect_script_type, general_custom_change_warning, \
nonwallet_custom_change_warning, sweep_custom_change_warning, EngineError,\ nonwallet_custom_change_warning, sweep_custom_change_warning, EngineError,\
TYPE_P2WPKH TYPE_P2WPKH, check_and_start_tor
from jmclient.wallet import BaseWallet from jmclient.wallet import BaseWallet
from qtsupport import ScheduleWizard, TumbleRestartWizard, config_tips,\ from qtsupport import ScheduleWizard, TumbleRestartWizard, config_tips,\
@ -2376,6 +2376,8 @@ if not jm_single().config.get("POLICY", "segwit") == "true":
update_config_for_gui() update_config_for_gui()
check_and_start_tor()
def onTabChange(i): def onTabChange(i):
""" Respond to change of tab. """ 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.support import EXIT_FAILURE
from jmbase import bintohex 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 from jmclient.fidelity_bond import FidelityBondProof
import sybil_attack_calculations as sybil import sybil_attack_calculations as sybil
@ -803,6 +803,7 @@ def main():
default=62601) default=62601)
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
load_program_config(config_path=options.datadir) load_program_config(config_path=options.datadir)
check_and_start_tor()
hostport = (options.host, options.port) hostport = (options.host, options.port)
mcs = [ObIRCMessageChannel(c) for c in get_irc_mchannels()] mcs = [ObIRCMessageChannel(c) for c in get_irc_mchannels()]
mcc = MessageChannelCollection(mcs) 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, \ get_sendpayment_parser, get_max_cj_fee_values, check_regtest, \
parse_payjoin_setup, send_payjoin, general_custom_change_warning, \ parse_payjoin_setup, send_payjoin, general_custom_change_warning, \
nonwallet_custom_change_warning, sweep_custom_change_warning, \ nonwallet_custom_change_warning, sweep_custom_change_warning, \
EngineError EngineError, check_and_start_tor
from twisted.python.log import startLogging from twisted.python.log import startLogging
from jmbase.support import get_log, jmprint, \ from jmbase.support import get_log, jmprint, \
EXIT_FAILURE, EXIT_ARGERROR EXIT_FAILURE, EXIT_ARGERROR
@ -63,6 +63,8 @@ def main():
" wallet, amount, destination address or wallet, bitcoin_uri.") " wallet, amount, destination address or wallet, bitcoin_uri.")
sys.exit(EXIT_ARGERROR) sys.exit(EXIT_ARGERROR)
check_and_start_tor()
#without schedule file option, use the arguments to create a schedule #without schedule file option, use the arguments to create a schedule
#of a single transaction #of a single transaction
sweeping = False sweeping = False

Loading…
Cancel
Save