Browse Source

simplified joinmarket dependencies installation

updated xenial and stretch dockerfiles since they bundle old versions of libsodium

refacatoring to make BlockchainInterface and BitcoinCoreNoHistoryInterface python2 compatible

add the -acceptnonstdtxn flag when invoking bitcoind for versions >= 0.19.0

refactor the use of nonlocal to make it compatible with python2

document the get_bitcoind_version method
master
Tim Akinbo 6 years ago
parent
commit
18d8f9668c
  1. 24
      .travis.yml
  2. 3
      README.md
  3. 25
      conftest.py
  4. 14
      docs/INSTALL.md
  5. 2
      docs/TESTING.md
  6. 141
      install.sh
  7. 102
      jmclient/jmclient/blockchaininterface.py
  8. 11
      jmclient/test/test_walletservice.py
  9. 2
      jmdaemon/test/test_irc_messaging.py
  10. 4
      requirements/base.txt
  11. 4
      requirements/gui.txt
  12. 1
      requirements/testing.txt
  13. 7
      test/Dockerfiles/bionic-py2.Dockerfile
  14. 7
      test/Dockerfiles/bionic-py3.Dockerfile
  15. 8
      test/Dockerfiles/build_docker.sh
  16. 4
      test/Dockerfiles/centos7-py2.Dockerfile
  17. 5
      test/Dockerfiles/fedora27-py2.Dockerfile
  18. 5
      test/Dockerfiles/fedora27-py3.Dockerfile
  19. 2
      test/Dockerfiles/stretch-py3.Dockerfile
  20. 2
      test/Dockerfiles/xenial-py3.Dockerfile
  21. 28
      test/regtest_joinmarket.cfg
  22. 5
      test/run_tests.sh

24
.travis.yml

@ -4,6 +4,12 @@ matrix:
include: include:
- os: osx - os: osx
env: PIP_DOWNLOAD_CACHE=$HOME/Library/Caches/pip env: PIP_DOWNLOAD_CACHE=$HOME/Library/Caches/pip
addons:
homebrew:
packages:
- bitcoin
- libsodium
update: true
- os: linux - os: linux
env: PIP_DOWNLOAD_CACHE=$HOME/.cache/pip env: PIP_DOWNLOAD_CACHE=$HOME/.cache/pip
addons: addons:
@ -13,6 +19,10 @@ matrix:
key_url: 'http://keyserver.ubuntu.com:11371/pks/lookup?op=get&search=0xD46F45428842CE5E' key_url: 'http://keyserver.ubuntu.com:11371/pks/lookup?op=get&search=0xD46F45428842CE5E'
packages: packages:
- bitcoind - bitcoind
- python3-dev
- python3-pip
- python-virtualenv
- libsodium18
- os: linux - os: linux
services: docker services: docker
env: DOCKER_IMG_JM=xenial-py2 env: DOCKER_IMG_JM=xenial-py2
@ -44,26 +54,30 @@ before_install:
- do_on(){ if [ "$TRAVIS_OS_NAME" = "$1" ]; then shift; "$@" ; fi; } - do_on(){ if [ "$TRAVIS_OS_NAME" = "$1" ]; then shift; "$@" ; fi; }
- on_host(){ if [ -z "$DOCKER_IMG_JM" ]; then "$@" ; fi; } - on_host(){ if [ -z "$DOCKER_IMG_JM" ]; then "$@" ; fi; }
- should_run_dockers(){ if [ "$TRAVIS_EVENT_TYPE" = cron ] || [ -n "$TRAVIS_TAG" ] || echo "${TRAVIS_COMMIT_MESSAGE[@]}" | grep -q "TRAVIS_RUN_DOCKERS"; then return 0; else return 1; fi; } - should_run_dockers(){ if [ "$TRAVIS_EVENT_TYPE" = cron ] || [ -n "$TRAVIS_TAG" ] || echo "${TRAVIS_COMMIT_MESSAGE[@]}" | grep -q "TRAVIS_RUN_DOCKERS"; then return 0; else return 1; fi; }
- on_docker(){ if [ -n "$DOCKER_IMG_JM" ] && should_run_dockers; then "$@" ; fi; } - on_docker(){ if [ -n "$DOCKER_IMG_JM" ]; then "$@" ; fi; }
- do_on osx pip install virtualenv - do_on osx pip install virtualenv
cache: cache:
directories: directories:
- $HOME/downloads - $HOME/downloads
- $HOME/.cache/pip - $HOME/.cache/pip
- $HOME/Library/Caches/pip - $HOME/Library/Caches/pip
- $HOME/Library/Caches/Homebrew
before_cache:
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then brew cleanup; fi
install: install:
- mkdir -p "$HOME/downloads" - mkdir -p "$HOME/downloads"
- mkdir -p "$TRAVIS_BUILD_DIR/deps/cache/" - mkdir -p "$TRAVIS_BUILD_DIR/deps/cache/"
- find "$HOME/downloads" -type f -exec cp -v {} "$TRAVIS_BUILD_DIR/deps/cache/" \; - find "$HOME/downloads" -type f -exec cp -v {} "$TRAVIS_BUILD_DIR/deps/cache/" \;
- on_host ./install.sh --develop --python=python3 --with-qt - on_host do_on linux ./install.sh --develop --python=python3 --with-qt
- on_host do_on osx virtualenv --python=python3 jmvenv
- on_host find "$TRAVIS_BUILD_DIR/deps/cache/" -type f -exec cp -v {} "$HOME/downloads/" \; - on_host find "$TRAVIS_BUILD_DIR/deps/cache/" -type f -exec cp -v {} "$HOME/downloads/" \;
before_script: before_script:
- on_host source jmvenv/bin/activate - on_host source jmvenv/bin/activate
script: script:
- on_host do_on linux bitcoind --help | head -1 - on_host bitcoind --help | head -1
- on_host do_on linux ./test/run_tests.sh - on_host ./test/run_tests.sh
- on_host do_on linux flake8 jmbase jmbitcoin jmclient jmdaemon scripts test - on_host do_on linux flake8 jmbase jmbitcoin jmclient jmdaemon scripts test
- on_docker ./test/Dockerfiles/build_docker.sh - on_docker ./test/Dockerfiles/build_docker.sh
after_success: after_success:
- on_docker echo "Success !" - on_docker echo "Success !"
- on_host do_on linux coveralls - on_host coveralls

3
README.md

@ -68,8 +68,7 @@ If binaries are built, they will be gpg signed and announced on the Releases pag
If you haven't chosen the Qt option during installation with `install.sh`, then to run the script `joinmarket-qt.py` from the command line you will need to install two more packages. Use these 2 commands while the `jmvenv` virtual environment is activated: If you haven't chosen the Qt option during installation with `install.sh`, then to run the script `joinmarket-qt.py` from the command line you will need to install two more packages. Use these 2 commands while the `jmvenv` virtual environment is activated:
``` ```
pip install PySide2 pip install -r requirements/gui.txt
pip install https://github.com/sunu/qt5reactor/archive/58410aaead2185e9917ae9cac9c50fe7b70e4a60.zip
``` ```
After this, the command `python joinmarket-qt.py` from within the `scripts` subdirectory should work. After this, the command `python joinmarket-qt.py` from within the `scripts` subdirectory should work.
There is a [walkthrough](docs/JOINMARKET-QT-GUIDE.md) for what to do next. There is a [walkthrough](docs/JOINMARKET-QT-GUIDE.md) for what to do next.

25
conftest.py

@ -2,6 +2,7 @@ from __future__ import (absolute_import, division,
print_function, unicode_literals) print_function, unicode_literals)
from builtins import * from builtins import *
import pytest import pytest
import re
import os import os
import time import time
import subprocess import subprocess
@ -12,6 +13,14 @@ bitcoin_rpcpassword = None
bitcoin_rpcusername = None bitcoin_rpcusername = None
miniircd_procs = [] miniircd_procs = []
def get_bitcoind_version(version_string):
# this utility function returns the version number
# as a tuple in the form (major, minor, patch)
version_tuple = re.match(
b'.*v(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)',
version_string).groups()
return tuple(map(lambda x: int(x), version_tuple))
def local_command(command, bg=False, redirect=''): def local_command(command, bg=False, redirect=''):
if redirect == 'NULL': if redirect == 'NULL':
if OS == 'Windows': if OS == 'Windows':
@ -96,10 +105,20 @@ def setup(request):
"--motd=" + cwd + "/miniircd/testmotd"], "--motd=" + cwd + "/miniircd/testmotd"],
bg=True) bg=True)
miniircd_procs.append(miniircd_proc) miniircd_procs.append(miniircd_proc)
# determine bitcoind version
bitcoind_version_string = subprocess.check_output([bitcoin_path + "bitcoind", "-version"]).split(b'\n')[0]
bitcoind_version = get_bitcoind_version(bitcoind_version_string)
#start up regtest blockchain #start up regtest blockchain
btc_proc = subprocess.call([bitcoin_path + "bitcoind", "-regtest", bitcoin_args = ["-regtest", "-daemon", "-conf=" + bitcoin_conf]
"-daemon", "-conf=" + bitcoin_conf])
time.sleep(3) #for bitcoin-core >= 0.19
if not (bitcoind_version[0] == 0 and bitcoind_version[1] < 19):
bitcoin_args += ['-acceptnonstdtxn']
btc_proc = subprocess.call([bitcoin_path + "bitcoind"] + bitcoin_args)
time.sleep(4)
#generate blocks; segwit activates around block 500-600 #generate blocks; segwit activates around block 500-600
root_cmd = [bitcoin_path + "bitcoin-cli", "-regtest", root_cmd = [bitcoin_path + "bitcoin-cli", "-regtest",
"-rpcuser=" + bitcoin_rpcusername, "-rpcuser=" + bitcoin_rpcusername,

14
docs/INSTALL.md

@ -26,7 +26,7 @@ is actually newer in version number, than what was there already.
To install everything (client and server), install these packages: To install everything (client and server), install these packages:
sudo apt-get install python-dev python-pip git build-essential automake pkg-config libtool libffi-dev libssl-dev libgmp-dev sudo apt-get install python3-dev python3-pip git build-essential automake pkg-config libtool libffi-dev libssl-dev libgmp-dev
(+ `libsodium-dev` if you can find it, else build after) (+ `libsodium-dev` if you can find it, else build after)
@ -49,7 +49,7 @@ Then install this repo:
Then: Then:
sudo pip install virtualenv sudo pip install virtualenv
virtualenv jmvenv virtualenv --python=python3 jmvenv
source jmvenv/bin/activate source jmvenv/bin/activate
**At this point you should see `(jmvenv)` at the beginning of your command prompt.** **At this point you should see `(jmvenv)` at the beginning of your command prompt.**
@ -57,10 +57,9 @@ Then:
#### Installing packages to run everything in-one: #### Installing packages to run everything in-one:
> *NOTE*: It is very important to have activated virtualenv before running this step. Otherwise, `setupall.py` will fail, you may be tempted to re-run it with `sudo setupall.py` which will cause problems in the future. > *NOTE*: It is very important to have activated virtualenv before running this step. Otherwise, `pip install` will fail, you may be tempted to re-run it with `sudo pip install` which will cause problems in the future.
python setupall.py --daemon pip install -r requirements/base.txt
python setupall.py --client-bitcoin
If you have installed this "full" version of the client, you can use it with the If you have installed this "full" version of the client, you can use it with the
command line scripts as explained in the [scripts README](https://github.com/AdamISZ/joinmarket-clientserver/tree/master/scripts). command line scripts as explained in the [scripts README](https://github.com/AdamISZ/joinmarket-clientserver/tree/master/scripts).
@ -94,10 +93,7 @@ command line scripts as explained in the [scripts README](https://github.com/Ada
``` ```
6) Setup joinmarket-qt 6) Setup joinmarket-qt
``` ```
pip install PySide2 pip install -r requirements/gui.txt
pip install qrcode[pil]
pip install https://github.com/sunu/qt5reactor/archive/58410aaead2185e9917ae9cac9c50fe7b70e4a60.zip
python setupall.py --all
``` ```
7) Start joinmarket-qt 7) Start joinmarket-qt
``` ```

2
docs/TESTING.md

@ -9,7 +9,7 @@ Make sure to have [bitcoind](https://bitcoin.org/en/full-node) 0.17 or newer ins
Install the test requirements (still in your virtualenv as mentioned above): Install the test requirements (still in your virtualenv as mentioned above):
pip install -r requirements-dev.txt pip install -r requirements/testing.txt
Running the test suite should be done something like (advisable to wipe ~/.bitcoin/regtest first): Running the test suite should be done something like (advisable to wipe ~/.bitcoin/regtest first):

141
install.sh

@ -13,20 +13,22 @@ sha256_verify ()
deps_install () deps_install ()
{ {
common_deps=( \
'python-virtualenv' \
'curl' \
'build-essential' \
'automake' \
'pkg-config' \
'libtool' \
'libgmp-dev' )
if [[ ${install_os} == 'debian' ]]; then if [[ ${install_os} == 'debian' ]]; then
if is_python3; then if is_python3; then
if deb_deps_install "python-virtualenv curl python3-dev python3-pip build-essential automake pkg-config libtool libgmp-dev libltdl-dev libssl-dev"; then deb_deps_install "${common_deps[@]} python3-dev python3-pip"
return 0
else
return 1
fi
else
if deb_deps_install "python-virtualenv curl python-dev python-pip build-essential automake pkg-config libtool libgmp-dev libltdl-dev libssl-dev"; then
return 0
else else
return 1 deb_deps_install "${common_deps[@]} python-dev python-pip"
fi
fi fi
return "$?"
else else
echo "OS can not be determined. Trying to build." echo "OS can not be determined. Trying to build."
return 0 return 0
@ -212,80 +214,6 @@ libffi_install ()
popd popd
} }
coincurve_patch_ignore_sys_libsecp ()
{
cat <<'EOF' > setup_support.py.patch
74c74,77
< ffi.dlopen("secp256k1")
---
> if "COINCURVE_IGNORE_SYSTEM_LIB" in os.environ:
> return False
> else:
> ffi.dlopen("secp256k1")
EOF
cat <<'EOF' > setup.py.patch
216,218c216
< self.library_dirs.append(
< os.path.join(_build_clib.build_clib, 'lib'),
< )
---
> self.library_dirs.insert(0, os.path.join(_build_clib.build_clib, 'lib'))
EOF
patch setup.py setup.py.patch && \
patch setup_support.py setup_support.py.patch
}
coincurve_build ()
{
if ! coincurve_patch_ignore_sys_libsecp; then
return 1
fi
if [[ -d "${jm_deps}/secp256k1-${secp256k1_version}" ]]; then
unlink ./libsecp256k1
ln -sf "${jm_source}/deps/secp256k1-${secp256k1_version}" ./libsecp256k1
else
return 1
fi
COINCURVE_IGNORE_SYSTEM_LIB="1" python setup.py install
return "$?"
}
coincurve_install ()
{
coincurve_version='9.0.0'
coincurve_lib_tar="${coincurve_version}.tar.gz"
coincurve_lib_sha='81561e954b4a978231e6611ae6153740bfbaebb214caff7a7b4e71fe9affbe09'
coincurve_url='https://github.com/ofek/coincurve/archive'
rm -rf "./coincurve-${coincurve_version}"
if ! dep_get "${coincurve_lib_tar}" "${coincurve_lib_sha}" "${coincurve_url}"; then
return 1
fi
pushd "coincurve-${coincurve_version}"
if ! coincurve_build; then
return 1
fi
popd
}
libsecp256k1_install ()
{
secp256k1_version='1e6f1f5ad5e7f1e3ef79313ec02023902bf8175c'
secp256k1_lib_tar="${secp256k1_version}.tar.gz"
secp256k1_lib_sha='d4bc033398d4db43077ceb3aa50bb2f7700bdf3fc6eb95b8c799ff6f657a804a'
secp256k1_url='https://github.com/bitcoin-core/secp256k1/archive'
if check_skip_build "secp256k1-${secp256k1_version}"; then
return 0
fi
if ! dep_get "${secp256k1_lib_tar}" "${secp256k1_lib_sha}" "${secp256k1_url}"; then
return 1
fi
if ! coincurve_install; then
return 1
fi
}
libsodium_build () libsodium_build ()
{ {
make uninstall make uninstall
@ -326,12 +254,14 @@ libsodium_install ()
joinmarket_install () joinmarket_install ()
{ {
jm_pkgs=( 'jmbase' 'jmdaemon' 'jmbitcoin' 'jmclient' ) reqs=( 'base.txt' )
for pkg in ${jm_pkgs[@]}; do
pip uninstall -y "${pkg/jm/joinmarket}" if [[ ${with_qt} = "1" ]]; then
pushd "${pkg}" reqs+=( 'gui.txt' )
pip install ${develop_build:+-e} . || return 1 fi
popd
for req in ${reqs[@]}; do
pip install -r "requirements/${req}" || return 1
done done
} }
@ -373,7 +303,7 @@ Usage: "${0}" [options]
Options: Options:
--develop code remains editable in place --develop code remains editable in place (currently always enabled)
--python, -p python version (default: python3) --python, -p python version (default: python3)
--with-qt build the Qt GUI (incompatible with python2) --with-qt build the Qt GUI (incompatible with python2)
--without-qt don't build the Qt GUI --without-qt don't build the Qt GUI
@ -405,17 +335,13 @@ os_is_deb ()
is_python3 () is_python3 ()
{ {
if [[ ${python} == 'python3' ]]; then if [[ ${python} == python3* ]]; then
return 0 return 0
fi fi
if [[ ${python} == 'python2' ]]; then if [[ ${python} == python2* ]]; then
return 1
fi
if eval "${python} -c 'import sys; sys.exit(0) if sys.version_info >= (3,0) else sys.exit(1)'"; then
return 0
else
return 1 return 1
fi fi
${python} -c 'import sys; sys.exit(0) if sys.version_info >= (3,0) else sys.exit(1)'
} }
install_get_os () install_get_os ()
@ -427,16 +353,6 @@ install_get_os ()
fi fi
} }
qt_deps_install ()
{
pip install \
PySide2 \
qrcode[pil] \
https://github.com/sunu/qt5reactor/archive/58410aaead2185e9917ae9cac9c50fe7b70e4a60.zip
return "$?"
}
main () main ()
{ {
jm_source="$PWD" jm_source="$PWD"
@ -480,10 +396,6 @@ main ()
echo "Libffi was not built. Exiting." echo "Libffi was not built. Exiting."
return 1 return 1
fi fi
if ! libsecp256k1_install; then
echo "libsecp256k1 was not build. Exiting."
return 1
fi
if ! libsodium_install; then if ! libsodium_install; then
echo "Libsodium was not built. Exiting." echo "Libsodium was not built. Exiting."
return 1 return 1
@ -494,11 +406,6 @@ main ()
deactivate deactivate
return 1 return 1
fi fi
if [[ ${with_qt} == 1 ]]; then
if ! qt_deps_install; then
echo "Qt dependencies could not be installed. Joinmarket-Qt might not work."
fi
fi
deactivate deactivate
echo "Joinmarket successfully installed echo "Joinmarket successfully installed
Before executing scripts or tests, run: Before executing scripts or tests, run:

102
jmclient/jmclient/blockchaininterface.py

@ -33,7 +33,6 @@ class BlockchainInterface(object):
except JsonRpcError: except JsonRpcError:
return len(self.rpc('getaddressinfo', [addr])['labels']) > 0 return len(self.rpc('getaddressinfo', [addr])['labels']) > 0
@abc.abstractmethod
def is_address_labeled(self, utxo, walletname): def is_address_labeled(self, utxo, walletname):
"""checks that UTXO belongs to the JM wallet""" """checks that UTXO belongs to the JM wallet"""
@ -58,7 +57,6 @@ class BlockchainInterface(object):
required for inclusion in the next N blocks. required for inclusion in the next N blocks.
''' '''
@abc.abstractmethod
def import_addresses_if_needed(self, addresses, wallet_name): def import_addresses_if_needed(self, addresses, wallet_name):
"""import addresses to the underlying blockchain interface if needed """import addresses to the underlying blockchain interface if needed
returns True if the sync call needs to do a system exit""" returns True if the sync call needs to do a system exit"""
@ -390,7 +388,53 @@ class BitcoinCoreInterface(BlockchainInterface):
return 10000 return 10000
return int(Decimal(1e8) * Decimal(estimate)) return int(Decimal(1e8) * Decimal(estimate))
class BitcoinCoreNoHistoryInterface(BitcoinCoreInterface): class RegtestBitcoinCoreMixin():
"""
This Mixin provides helper functions that are used in Interface classes
requiring some functionality only useful on the regtest network.
"""
def tick_forward_chain(self, n):
"""
Special method for regtest only;
instruct to mine n blocks.
"""
try:
self.rpc('generatetoaddress', [n, self.destn_addr])
except JsonRpcConnectionError:
#can happen if the blockchain is shut down
#automatically at the end of tests; this shouldn't
#trigger an error
log.debug(
"Failed to generate blocks, looks like the bitcoin daemon \
has been shut down. Ignoring.")
def grab_coins(self, receiving_addr, amt=50):
"""
NOTE! amt is passed in Coins, not Satoshis!
Special method for regtest only:
take coins from bitcoind's own wallet
and put them in the receiving addr.
Return the txid.
"""
if amt > 500:
raise Exception("too greedy")
"""
if amt > self.current_balance:
#mine enough to get to the reqd amt
reqd = int(amt - self.current_balance)
reqd_blocks = int(reqd/50) +1
if self.rpc('setgenerate', [True, reqd_blocks]):
raise Exception("Something went wrong")
"""
# now we do a custom create transaction and push to the receiver
txid = self.rpc('sendtoaddress', [receiving_addr, amt])
if not txid:
raise Exception("Failed to broadcast transaction")
# confirm
self.tick_forward_chain(1)
return txid
class BitcoinCoreNoHistoryInterface(BitcoinCoreInterface, RegtestBitcoinCoreMixin):
def __init__(self, jsonRpc, network): def __init__(self, jsonRpc, network):
super(BitcoinCoreNoHistoryInterface, self).__init__(jsonRpc, network) super(BitcoinCoreNoHistoryInterface, self).__init__(jsonRpc, network)
@ -463,22 +507,15 @@ class BitcoinCoreNoHistoryInterface(BitcoinCoreInterface):
# avoidance of address reuse # avoidance of address reuse
wallet.disable_new_scripts = True wallet.disable_new_scripts = True
##these two functions are hacks to make the test code be able to use the
##same helper functions, perhaps it would be nicer to create mixin classes
##and use multiple inheritance to make the code more OOP, but its not
##worth it now
def grab_coins(self, receiving_addr, amt=50):
RegtestBitcoinCoreInterface.grab_coins(self, receiving_addr, amt)
def tick_forward_chain(self, n): def tick_forward_chain(self, n):
self.destn_addr = self.rpc("getnewaddress", []) self.destn_addr = self.rpc("getnewaddress", [])
RegtestBitcoinCoreInterface.tick_forward_chain(self, n) super(BitcoinCoreNoHistoryInterface, self).tick_forward_chain(n)
# class for regtest chain access # class for regtest chain access
# running on local daemon. Only # running on local daemon. Only
# to be instantiated after network is up # to be instantiated after network is up
# with > 100 blocks. # with > 100 blocks.
class RegtestBitcoinCoreInterface(BitcoinCoreInterface): #pragma: no cover class RegtestBitcoinCoreInterface(BitcoinCoreInterface, RegtestBitcoinCoreMixin): #pragma: no cover
def __init__(self, jsonRpc): def __init__(self, jsonRpc):
super(RegtestBitcoinCoreInterface, self).__init__(jsonRpc, 'regtest') super(RegtestBitcoinCoreInterface, self).__init__(jsonRpc, 'regtest')
@ -526,47 +563,6 @@ class RegtestBitcoinCoreInterface(BitcoinCoreInterface): #pragma: no cover
self.tick_forward_chain, 1) self.tick_forward_chain, 1)
return ret return ret
def tick_forward_chain(self, n):
"""
Special method for regtest only;
instruct to mine n blocks.
"""
try:
self.rpc('generatetoaddress', [n, self.destn_addr])
except JsonRpcConnectionError:
#can happen if the blockchain is shut down
#automatically at the end of tests; this shouldn't
#trigger an error
log.debug(
"Failed to generate blocks, looks like the bitcoin daemon \
has been shut down. Ignoring.")
def grab_coins(self, receiving_addr, amt=50):
"""
NOTE! amt is passed in Coins, not Satoshis!
Special method for regtest only:
take coins from bitcoind's own wallet
and put them in the receiving addr.
Return the txid.
"""
if amt > 500:
raise Exception("too greedy")
"""
if amt > self.current_balance:
#mine enough to get to the reqd amt
reqd = int(amt - self.current_balance)
reqd_blocks = int(reqd/50) +1
if self.rpc('setgenerate', [True, reqd_blocks]):
raise Exception("Something went wrong")
"""
# now we do a custom create transaction and push to the receiver
txid = self.rpc('sendtoaddress', [receiving_addr, amt])
if not txid:
raise Exception("Failed to broadcast transaction")
# confirm
self.tick_forward_chain(1)
return txid
def get_received_by_addr(self, addresses, query_params): def get_received_by_addr(self, addresses, query_params):
# NB This will NOT return coinbase coins (but wont matter in our use # NB This will NOT return coinbase coins (but wont matter in our use
# case). allow importaddress to fail in case the address is already # case). allow importaddress to fail in case the address is already

11
jmclient/test/test_walletservice.py

@ -40,11 +40,10 @@ def test_address_reuse_freezing(setup_walletservice):
called, and that the balance available in the mixdepth correctly called, and that the balance available in the mixdepth correctly
reflects the usage pattern and freeze policy. reflects the usage pattern and freeze policy.
""" """
cb_called = 0 context = {'cb_called': 0}
def reuse_callback(utxostr): def reuse_callback(utxostr):
nonlocal cb_called
print("Address reuse freezing callback on utxo: ", utxostr) print("Address reuse freezing callback on utxo: ", utxostr)
cb_called += 1 context['cb_called'] += 1
# we must fund after initial sync (for imports), hence # we must fund after initial sync (for imports), hence
# "populated" with no coins # "populated" with no coins
wallet = get_populated_wallet(num=0) wallet = get_populated_wallet(num=0)
@ -59,16 +58,16 @@ def test_address_reuse_freezing(setup_walletservice):
# check that with default status any reuse is blocked: # check that with default status any reuse is blocked:
try_address_reuse(wallet_service, 0, 1, -1, 3 * 10**8) try_address_reuse(wallet_service, 0, 1, -1, 3 * 10**8)
assert cb_called == 1, "Failed to trigger freeze callback" assert context['cb_called'] == 1, "Failed to trigger freeze callback"
# check that above the threshold is allowed (1 sat less than funding) # check that above the threshold is allowed (1 sat less than funding)
try_address_reuse(wallet_service, 1, 1, 99999999, 4 * 10**8) try_address_reuse(wallet_service, 1, 1, 99999999, 4 * 10**8)
assert cb_called == 1, "Incorrectly triggered freeze callback" assert context['cb_called'] == 1, "Incorrectly triggered freeze callback"
# check that below the threshold on the same address is not allowed: # check that below the threshold on the same address is not allowed:
try_address_reuse(wallet_service, 1, 0.99999998, 99999999, 4 * 10**8) try_address_reuse(wallet_service, 1, 0.99999998, 99999999, 4 * 10**8)
# note can be more than 1 extra call here, somewhat suboptimal: # note can be more than 1 extra call here, somewhat suboptimal:
assert cb_called > 1, "Failed to trigger freeze callback" assert context['cb_called'] > 1, "Failed to trigger freeze callback"
@pytest.fixture(scope='module') @pytest.fixture(scope='module')

2
jmdaemon/test/test_irc_messaging.py

@ -129,7 +129,7 @@ class TrialIRC(unittest.TestCase):
def test_waiter(self): def test_waiter(self):
print("test_main()") print("test_main()")
#reactor.callLater(1.0, junk_messages, self.mcc) #reactor.callLater(1.0, junk_messages, self.mcc)
return task.deferLater(reactor, 22, self._called_by_deffered) return task.deferLater(reactor, 30, self._called_by_deffered)
def _called_by_deffered(self): def _called_by_deffered(self):
pass pass

4
requirements/base.txt

@ -0,0 +1,4 @@
-e ./jmbase
-e ./jmbitcoin
-e ./jmclient
-e ./jmdaemon

4
requirements/gui.txt

@ -0,0 +1,4 @@
-r base.txt
PySide2
qrcode[pil]
https://github.com/sunu/qt5reactor/archive/58410aaead2185e9917ae9cac9c50fe7b70e4a60.zip#egg=qt5reactor

1
requirements-dev.txt → requirements/testing.txt

@ -1,3 +1,4 @@
-r base.txt
# matplotlib # matplotlib
# numpy # numpy
pexpect pexpect

7
test/Dockerfiles/bionic-py2.Dockerfile

@ -3,11 +3,8 @@ SHELL ["/bin/bash", "-c"]
# dependencies # dependencies
RUN apt-get update RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y \ RUN apt-get install -y \
automake pkg-config libtool libgmp-dev python-dev python-pip python-virtualenv libsodium23
RUN apt-get install -y \
python-dev python-pip python-virtualenv python-qt4 python-sip
# curl is a better tool # curl is a better tool
RUN apt-get install -y curl RUN apt-get install -y curl
@ -33,5 +30,5 @@ RUN bitcoind --version | head -1
# install script # install script
WORKDIR ${repo_name} WORKDIR ${repo_name}
RUN ./install.sh --python=python2 RUN virtualenv --python=python2 jmvenv
RUN source jmvenv/bin/activate && ./test/run_tests.sh RUN source jmvenv/bin/activate && ./test/run_tests.sh

7
test/Dockerfiles/bionic-py3.Dockerfile

@ -3,11 +3,8 @@ SHELL ["/bin/bash", "-c"]
# dependencies # dependencies
RUN apt-get update RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y \ RUN apt-get install -y \
automake pkg-config libtool libgmp-dev python3-dev python3-pip python-virtualenv libsodium23
RUN apt-get install -y \
python3-dev python3-pip python-virtualenv python3-pyqt4 python3-sip
# curl is a better tool # curl is a better tool
RUN apt-get install -y curl RUN apt-get install -y curl
@ -33,5 +30,5 @@ RUN bitcoind --version | head -1
# install script # install script
WORKDIR ${repo_name} WORKDIR ${repo_name}
RUN echo y | ./install.sh --python=python3 RUN virtualenv --python=python3 jmvenv
RUN source jmvenv/bin/activate && ./test/run_tests.sh RUN source jmvenv/bin/activate && ./test/run_tests.sh

8
test/Dockerfiles/build_docker.sh

@ -15,14 +15,10 @@ build_docker ()
return 0 return 0
fi fi
core_version='0.17.1' core_version='0.18.0'
core_dist="bitcoin-${core_version}-x86_64-linux-gnu.tar.gz" core_dist="bitcoin-${core_version}-x86_64-linux-gnu.tar.gz"
core_url="https://bitcoincore.org/bin/bitcoin-core-${core_version}/${core_dist}" core_url="https://bitcoincore.org/bin/bitcoin-core-${core_version}/${core_dist}"
libffi_lib_tar='v3.2.1.tar.gz' declare -A deps=( [${core_dist}]="${core_url}" )
libffi_url="https://github.com/libffi/libffi/archive/${libffi_lib_tar}"
sodium_lib_tar='libsodium-1.0.13.tar.gz'
sodium_url="https://download.libsodium.org/libsodium/releases/old/${sodium_lib_tar}"
declare -A deps=( [${core_dist}]="${core_url}" [${libffi_lib_tar}]="${libffi_url}" [${sodium_lib_tar}]="${sodium_url}" )
jm_root="${TRAVIS_BUILD_DIR}" jm_root="${TRAVIS_BUILD_DIR}"
owner_name="${TRAVIS_REPO_SLUG%\/*}" owner_name="${TRAVIS_REPO_SLUG%\/*}"
repo_name="${TRAVIS_REPO_SLUG#*\/}" repo_name="${TRAVIS_REPO_SLUG#*\/}"

4
test/Dockerfiles/centos7-py2.Dockerfile

@ -6,7 +6,7 @@ RUN yum -y groups install 'Development tools'
RUN yum -y install epel-release && \ RUN yum -y install epel-release && \
yum -y update yum -y update
RUN yum -y install \ RUN yum -y install \
python-devel python2-pip python-virtualenv gmp-devel python-devel python2-pip python-virtualenv libsodium
RUN useradd --home-dir /home/chaum --create-home --shell /bin/bash --skel /etc/skel/ chaum RUN useradd --home-dir /home/chaum --create-home --shell /bin/bash --skel /etc/skel/ chaum
ARG core_version ARG core_version
@ -29,5 +29,5 @@ RUN bitcoind --version | head -1
# install script # install script
WORKDIR ${repo_name} WORKDIR ${repo_name}
RUN ./install.sh --python=python2 RUN virtualenv --python=python2 jmvenv
RUN source jmvenv/bin/activate && ./test/run_tests.sh RUN source jmvenv/bin/activate && ./test/run_tests.sh

5
test/Dockerfiles/fedora27-py2.Dockerfile

@ -4,8 +4,7 @@ SHELL ["/bin/bash", "-c"]
# dependencies # dependencies
RUN dnf -y groups install 'Development tools' RUN dnf -y groups install 'Development tools'
RUN dnf -y install \ RUN dnf -y install \
autoconf libtool pkgconfig \ python-devel python-pip python2-virtualenv libsodium
python-devel python-pip python2-virtualenv gmp-devel
# needed for build time # needed for build time
# https://stackoverflow.com/questions/34624428/g-error-usr-lib-rpm-redhat-redhat-hardened-cc1-no-such-file-or-directory # https://stackoverflow.com/questions/34624428/g-error-usr-lib-rpm-redhat-redhat-hardened-cc1-no-such-file-or-directory
@ -32,5 +31,5 @@ RUN bitcoind --version | head -1
# install script # install script
WORKDIR ${repo_name} WORKDIR ${repo_name}
RUN ./install.sh --python=python2 RUN virtualenv --python=python2 jmvenv
RUN source jmvenv/bin/activate && ./test/run_tests.sh RUN source jmvenv/bin/activate && ./test/run_tests.sh

5
test/Dockerfiles/fedora27-py3.Dockerfile

@ -4,8 +4,7 @@ SHELL ["/bin/bash", "-c"]
# dependencies # dependencies
RUN dnf -y groups install 'Development tools' RUN dnf -y groups install 'Development tools'
RUN dnf -y install \ RUN dnf -y install \
autoconf libtool pkgconfig \ python3-devel python3-pip python-virtualenv libsodium
python3-devel python3-pip python-virtualenv gmp-devel
# needed for build time # needed for build time
# https://stackoverflow.com/questions/34624428/g-error-usr-lib-rpm-redhat-redhat-hardened-cc1-no-such-file-or-directory # https://stackoverflow.com/questions/34624428/g-error-usr-lib-rpm-redhat-redhat-hardened-cc1-no-such-file-or-directory
@ -32,5 +31,5 @@ RUN bitcoind --version | head -1
# install script # install script
WORKDIR ${repo_name} WORKDIR ${repo_name}
RUN echo y | ./install.sh --python=python3 RUN virtualenv --python=python3 jmvenv
RUN source jmvenv/bin/activate && ./test/run_tests.sh RUN source jmvenv/bin/activate && ./test/run_tests.sh

2
test/Dockerfiles/stretch-py3.Dockerfile

@ -33,5 +33,5 @@ RUN bitcoind --version | head -1
# install script # install script
WORKDIR ${repo_name} WORKDIR ${repo_name}
RUN echo y | ./install.sh --python=python3 RUN ./install.sh --python=python3 --with-qt
RUN source jmvenv/bin/activate && ./test/run_tests.sh RUN source jmvenv/bin/activate && ./test/run_tests.sh

2
test/Dockerfiles/xenial-py3.Dockerfile

@ -33,5 +33,5 @@ RUN bitcoind --version | head -1
# install script # install script
WORKDIR ${repo_name} WORKDIR ${repo_name}
RUN echo y | ./install.sh --python=python3 RUN ./install.sh --python=python3 --with-qt
RUN source jmvenv/bin/activate && ./test/run_tests.sh RUN source jmvenv/bin/activate && ./test/run_tests.sh

28
test/regtest_joinmarket.cfg

@ -14,15 +14,25 @@ rpc_user = bitcoinrpc
rpc_password = 123456abcdef rpc_password = 123456abcdef
network = testnet network = testnet
[MESSAGING] [MESSAGING:server1]
host = localhost, localhost host = localhost
hostid = localhost1, localhost2 hostid = localhost1
channel = joinmarket-pit, joinmarket-pit channel = joinmarket-pit
port = 6667, 6668 port = 6667
usessl = false, false usessl = false
socks5 = false, false socks5 = false
socks5_host = localhost, localhost socks5_host = localhost
socks5_port = 9150, 9150 socks5_port = 9150
[MESSAGING:server2]
host = localhost
hostid = localhost2
channel = joinmarket-pit
port = 6668
usessl = false
socks5 = false
socks5_host = localhost
socks5_port = 9150
[TIMEOUT] [TIMEOUT]
maker_timeout_sec = 15 maker_timeout_sec = 15

5
test/run_tests.sh

@ -19,6 +19,7 @@ run_jm_tests ()
\`source ./jmvenv/bin/activate\`" \`source ./jmvenv/bin/activate\`"
return 1 return 1
fi fi
jm_requirements="requirements/testing.txt"
jm_source="${VIRTUAL_ENV}/.." jm_source="${VIRTUAL_ENV}/.."
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${VIRTUAL_ENV}/lib/pkgconfig" export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${VIRTUAL_ENV}/lib/pkgconfig"
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${VIRTUAL_ENV}/lib" export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${VIRTUAL_ENV}/lib"
@ -33,8 +34,8 @@ run_jm_tests ()
mkdir -p miniircd mkdir -p miniircd
tar -xzf miniircd.tar.gz -C ./miniircd --strip-components=1 tar -xzf miniircd.tar.gz -C ./miniircd --strip-components=1
fi fi
if ! pip install -r ./requirements-dev.txt; then if ! pip install -r "${jm_requirements}"; then
echo "Packages in 'requirements-dev.txt' could not be installed. Exiting." echo "Packages in '${jm_requirements}' could not be installed. Exiting."
return 1 return 1
fi fi
if [[ ! -L ./joinmarket.cfg && -e ./joinmarket.cfg ]]; then if [[ ! -L ./joinmarket.cfg && -e ./joinmarket.cfg ]]; then

Loading…
Cancel
Save