Browse Source

Adds libsecp256k1 installation and addresses reviews

Update no-history-sync code:
This updates the new functionality in jmclient.wallet_utils
in the no-history-sync PR #444 to be compatible
with the python-bitcointx refactoring.

Remove all future/py2 compatibility code remaining:
This is in line with #525 and corrects erroneous
addition of more compatibility code.

Addresses all flake8 complaints (ununsed imports etc)

Addresses review of @dgpv

Addresses review of @kristapsk
master
Adam Gibson 6 years ago
parent
commit
03a13598e8
No known key found for this signature in database
GPG Key ID: 141001A1AF77F20B
  1. 38
      install.sh
  2. 16
      jmbase/jmbase/support.py
  3. 4
      jmbase/setup.py
  4. 2
      jmbitcoin/jmbitcoin/__init__.py
  5. 9
      jmbitcoin/jmbitcoin/secp256k1_ecies.py
  6. 35
      jmbitcoin/jmbitcoin/secp256k1_main.py
  7. 28
      jmbitcoin/jmbitcoin/secp256k1_transaction.py
  8. 6
      jmbitcoin/jmbitcoin/snicker.py
  9. 4
      jmbitcoin/setup.py
  10. 3
      jmbitcoin/test/test_ecdh.py
  11. 3
      jmbitcoin/test/test_ecies.py
  12. 5
      jmbitcoin/test/test_tx_signing.py
  13. 5
      jmclient/jmclient/client_protocol.py
  14. 5
      jmclient/jmclient/commitment_utils.py
  15. 4
      jmclient/jmclient/configure.py
  16. 10
      jmclient/jmclient/cryptoengine.py
  17. 3
      jmclient/jmclient/electruminterface.py
  18. 8
      jmclient/jmclient/maker.py
  19. 1
      jmclient/jmclient/podle.py
  20. 6
      jmclient/jmclient/snicker_receiver.py
  21. 6
      jmclient/jmclient/storage.py
  22. 23
      jmclient/jmclient/taker.py
  23. 16
      jmclient/jmclient/taker_utils.py
  24. 28
      jmclient/jmclient/wallet.py
  25. 5
      jmclient/jmclient/wallet_service.py
  26. 34
      jmclient/jmclient/wallet_utils.py
  27. 7
      jmclient/jmclient/yieldgenerator.py
  28. 5
      jmclient/setup.py
  29. 5
      jmclient/test/commontest.py
  30. 2
      jmclient/test/test_client_protocol.py
  31. 2
      jmclient/test/test_coinjoin.py
  32. 3
      jmclient/test/test_maker.py
  33. 2
      jmclient/test/test_payjoin.py
  34. 1
      jmclient/test/test_podle.py
  35. 8
      jmclient/test/test_privkeys.py
  36. 5
      jmclient/test/test_psbt_wallet.py
  37. 14
      jmclient/test/test_snicker.py
  38. 3
      jmclient/test/test_taker.py
  39. 5
      jmclient/test/test_tx_creation.py
  40. 3
      jmclient/test/test_wallet.py
  41. 1
      jmclient/test/test_wallets.py
  42. 3
      jmdaemon/jmdaemon/daemon_protocol.py
  43. 1
      jmdaemon/jmdaemon/irc.py
  44. 7
      jmdaemon/jmdaemon/message_channel.py
  45. 4
      jmdaemon/setup.py
  46. 3
      jmdaemon/test/test_daemon_protocol.py
  47. 5
      scripts/add-utxo.py
  48. 2
      scripts/joinmarket-qt.py
  49. 5
      scripts/sendtomany.py
  50. 11
      test/test_segwit.py

38
install.sh

@ -234,6 +234,40 @@ libffi_install ()
popd
}
libsecp256k1_build()
{
make clean
./autogen.sh
./configure \
--enable-module-recovery \
--disable-jni \
--prefix "${jm_root}" \
--enable-experimental \
--enable-module-ecdh \
--enable-benchmark=no
make
if ! make check; then
return 1
fi
}
libsecp256k1_install()
{
secp256k1_lib_tar='0d9540b13ffcd7cd44cc361b8744b93d88aa76ba'
secp256k1_lib_sha="0803d2dddbf6dd702c379118f066f638bcef6b07eea959f12d31ad2f4721fbe1"
secp256k1_lib_url='https://github.com/bitcoin-core/secp256k1/archive'
if ! dep_get "${secp256k1_lib_tar}.tar.gz" "${secp256k1_lib_sha}" "${secp256k1_lib_url}"; then
return 1
fi
pushd "secp256k1-${secp256k1_lib_tar}"
if libsecp256k1_build; then
make install
else
return 1
fi
popd
}
libsodium_build ()
{
make uninstall
@ -419,6 +453,10 @@ main ()
# echo "Openssl was not built. Exiting."
# return 1
# fi
if ! libsecp256k1_install; then
echo "libsecp256k1 was not built. Exiting."
return 1
fi
if ! libffi_install; then
echo "Libffi was not built. Exiting."
return 1

16
jmbase/jmbase/support.py

@ -220,9 +220,9 @@ def print_jm_version(option, opt_str, value, parser):
# helper functions for conversions of format between over-the-wire JM
# and internal. See details in hexbin() docstring.
def cv(x):
success, utxo = utxostr_to_utxo(x)
if success:
def _convert(x):
good, utxo = utxostr_to_utxo(x)
if good:
return utxo
else:
try:
@ -239,18 +239,18 @@ def listchanger(l):
elif isinstance(x, dict):
rlist.append(dictchanger(x))
else:
rlist.append(cv(x))
rlist.append(_convert(x))
return rlist
def dictchanger(d):
rdict = {}
for k, v in d.items():
if isinstance(v, dict):
rdict[cv(k)] = dictchanger(v)
rdict[_convert(k)] = dictchanger(v)
elif isinstance(v, list):
rdict[cv(k)] = listchanger(v)
rdict[_convert(k)] = listchanger(v)
else:
rdict[cv(k)] = cv(v)
rdict[_convert(k)] = _convert(v)
return rdict
def hexbin(func):
@ -276,7 +276,7 @@ def hexbin(func):
elif isinstance(arg, dict):
newargs.append(dictchanger(arg))
else:
newargs.append(cv(arg))
newargs.append(_convert(arg))
return func(inst, *newargs, **kwargs)
return func_wrapper

4
jmbase/setup.py

@ -9,7 +9,7 @@ setup(name='joinmarketbase',
author_email='',
license='GPL',
packages=['jmbase'],
install_requires=['future', 'twisted==19.7.0', 'service-identity',
install_requires=['twisted==19.7.0', 'service-identity',
'chromalog==1.0.5'],
python_requires='>=3.3',
python_requires='>=3.6',
zip_safe=False)

2
jmbitcoin/jmbitcoin/__init__.py

@ -13,7 +13,5 @@ from bitcointx.core import (x, b2x, b2lx, lx, COutPoint, CTxOut, CTxIn,
from bitcointx.core.key import KeyStore
from bitcointx.core.script import (CScript, OP_0, SignatureHash, SIGHASH_ALL,
SIGVERSION_WITNESS_V0, CScriptWitness)
from bitcointx.wallet import (CBitcoinSecret, P2WPKHBitcoinAddress, CCoinAddress,
P2SHCoinAddress)
from bitcointx.core.psbt import PartiallySignedTransaction

9
jmbitcoin/jmbitcoin/secp256k1_ecies.py

@ -1,8 +1,5 @@
#!/usr/bin/python
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from builtins import * # noqa: F401
from future.utils import native
import coincurve as secp256k1
import base64
import hmac
@ -19,7 +16,7 @@ class ECIESDecryptionError(Exception):
# AES primitives. See BIP-SNICKER for specification.
def aes_encrypt(key, data, iv):
encrypter = pyaes.Encrypter(
pyaes.AESModeOfOperationCBC(key, iv=native(iv)))
pyaes.AESModeOfOperationCBC(key, iv=iv))
enc_data = encrypter.feed(data)
enc_data += encrypter.feed()
@ -27,7 +24,7 @@ def aes_encrypt(key, data, iv):
def aes_decrypt(key, data, iv):
decrypter = pyaes.Decrypter(
pyaes.AESModeOfOperationCBC(key, iv=native(iv)))
pyaes.AESModeOfOperationCBC(key, iv=iv))
try:
dec_data = decrypter.feed(data)
dec_data += decrypter.feed()

35
jmbitcoin/jmbitcoin/secp256k1_main.py

@ -1,15 +1,11 @@
#!/usr/bin/python
from future.utils import native_bytes, bytes_to_native_str
import binascii
import hashlib
import sys
import base64
import struct
import coincurve as secp256k1
from bitcointx import base58
from bitcointx.core import Hash, CBitcoinTransaction
from bitcointx.core.key import CKeyBase, CPubKey
from bitcointx.core import Hash
from bitcointx.core.key import CKeyBase
from bitcointx.signmessage import BitcoinMessage
#Required only for PoDLE calculation:
@ -60,7 +56,7 @@ def privkey_to_pubkey(priv):
and return compressed/uncompressed public key as appropriate.'''
compressed, priv = read_privkey(priv)
#secp256k1 checks for validity of key value.
newpriv = secp256k1.PrivateKey(secret=native_bytes(priv))
newpriv = secp256k1.PrivateKey(secret=priv)
return newpriv.public_key.format(compressed)
# b58check wrapper functions around bitcointx.base58 functions:
@ -137,7 +133,7 @@ def multiply(s, pub, return_serialized=True):
'''
newpub = secp256k1.PublicKey(pub)
#see note to "tweak_mul" function in podle.py
res = newpub.multiply(native_bytes(s))
res = newpub.multiply(s)
if not return_serialized:
return res
return res.format()
@ -245,32 +241,9 @@ class JMCKey(bytes, CKeyBase):
def __init__(self, b):
CKeyBase.__init__(self, b, compressed=True)
def is_compressed(self):
return True
@property
def secret_bytes(self):
assert isinstance(self, bytes)
return self[:32]
def sign(self, hash):
assert isinstance(hash, (bytes, bytearray))
if len(hash) != 32:
raise ValueError('Hash must be exactly 32 bytes long')
# TODO: non default sighash flag.
return ecdsa_raw_sign(hash, self.secret_bytes + b"\x01", rawmsg=True)
def verify(self, hash, sig):
return self.pub.verify(hash, sig)
def verify_nonstrict(self, hash, sig):
return self.pub.verify_nonstrict(hash, sig)
@classmethod
def from_secret_bytes(cls, secret, compressed=True):
return cls(secret, compressed=compressed)
@classmethod
def from_bytes(cls, data):
raise NotImplementedError('subclasses must override from_bytes()')

28
jmbitcoin/jmbitcoin/secp256k1_transaction.py

@ -1,20 +1,14 @@
#!/usr/bin/python
from past.builtins import basestring
from io import BytesIO
import binascii
import copy
import re
import os
import struct
# note, only used for non-cryptographic randomness:
import random
from jmbitcoin.secp256k1_main import *
from bitcointx.core import (CMutableTransaction, Hash160, CTxInWitness,
CTxWitness, CMutableOutPoint, CMutableTxIn,
CMutableTxOut, ValidationError, lx, x)
CMutableOutPoint, CMutableTxIn,
CMutableTxOut, ValidationError)
from bitcointx.core.script import *
from bitcointx.wallet import P2WPKHBitcoinAddress, CCoinAddress
from bitcointx.wallet import P2WPKHCoinAddress, CCoinAddress, P2PKHCoinAddress
from bitcointx.core.scripteval import (VerifyScript, SCRIPT_VERIFY_WITNESS,
SCRIPT_VERIFY_P2SH, SIGVERSION_WITNESS_V0)
@ -74,10 +68,7 @@ def pubkey_to_p2pkh_script(pub, require_compressed=False):
representing the corresponding pay-to-pubkey-hash
scriptPubKey.
"""
if not is_valid_pubkey(pub, require_compressed=require_compressed):
raise Exception("Invalid pubkey")
return CScript([OP_DUP, OP_HASH160, Hash160(pub),
OP_EQUALVERIFY, OP_CHECKSIG])
return P2PKHCoinAddress.from_pubkey(pub).to_scriptPubKey()
def pubkey_to_p2wpkh_script(pub):
"""
@ -85,9 +76,7 @@ def pubkey_to_p2wpkh_script(pub):
representing the corresponding pay-to-witness-pubkey-hash
scriptPubKey.
"""
if not is_valid_pubkey(pub, True):
raise Exception("Invalid pubkey")
return CScript([OP_0, Hash160(pub)])
return P2WPKHCoinAddress.from_pubkey(pub).to_scriptPubKey()
def pubkey_to_p2sh_p2wpkh_script(pub):
"""
@ -146,8 +135,7 @@ def sign(tx, i, priv, hashcode=SIGHASH_ALL, amount=None, native=False):
return None, "Error in signing: " + repr(e)
assert isinstance(tx, CMutableTransaction)
# using direct local access to libsecp256k1 binding, because
# python-bitcoinlib uses OpenSSL key management:
pub = privkey_to_pubkey(priv)
if not amount:
@ -175,7 +163,7 @@ def sign(tx, i, priv, hashcode=SIGHASH_ALL, amount=None, native=False):
input_scriptPubKey = pubkey_to_p2wpkh_script(pub)
# only created for convenience access to scriptCode:
input_address = P2WPKHBitcoinAddress.from_scriptPubKey(input_scriptPubKey)
input_address = P2WPKHCoinAddress.from_scriptPubKey(input_scriptPubKey)
# function name is misleading here; redeemScript only applies to p2sh.
scriptCode = input_address.to_redeemScript()

6
jmbitcoin/jmbitcoin/snicker.py

@ -1,7 +1,3 @@
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from builtins import * # noqa: F401
# Implementation of proposal as per
# https://gist.github.com/AdamISZ/2c13fb5819bd469ca318156e2cf25d79
# (BIP SNICKER)
@ -45,7 +41,7 @@ def verify_snicker_output(tx, pub, tweak, spk_type='p2sh-p2wpkh'):
or -1 and None if it is not found exactly once.
TODO Add support for other scriptPubKey types.
"""
assert isinstance(tx, btc.CBitcoinTransaction)
assert isinstance(tx, btc.CTransaction)
expected_destination_pub = snicker_pubkey_tweak(pub, tweak)
expected_destination_spk = pubkey_to_p2sh_p2wpkh_script(expected_destination_pub)
found = 0

4
jmbitcoin/setup.py

@ -9,6 +9,6 @@ setup(name='joinmarketbitcoin',
author_email='',
license='GPL',
packages=['jmbitcoin'],
install_requires=['future', 'coincurve', 'urldecode',
'python-bitcointx>=1.0.5', 'pyaes'],
python_requires='>=3.6',
install_requires=['coincurve', 'python-bitcointx>=1.0.5', 'pyaes', 'urldecode'],
zip_safe=False)

3
jmbitcoin/test/test_ecdh.py

@ -1,7 +1,4 @@
#! /usr/bin/env python
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from builtins import * # noqa: F401
'''Tests coincurve binding to libsecp256k1 ecdh module code'''
import hashlib

3
jmbitcoin/test/test_ecies.py

@ -1,7 +1,4 @@
#! /usr/bin/env python
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from builtins import * # noqa: F401
'''Tests ECIES implementation as defined in BIP-SNICKER
(and will be updated if that is).'''

5
jmbitcoin/test/test_tx_signing.py

@ -1,6 +1,5 @@
#!/usr/bin/env python3
import sys
import pytest
import binascii
@ -26,7 +25,7 @@ def test_sign_standard_txs(addrtype):
# (note that the input utxo is fake so we are really only creating
# a destination here).
scriptPubKey = btc.CScript([btc.OP_0, btc.Hash160(pub)])
address = btc.P2WPKHBitcoinAddress.from_scriptPubKey(scriptPubKey)
address = btc.P2WPKHCoinAddress.from_scriptPubKey(scriptPubKey)
# Create a dummy outpoint; use same 32 bytes for convenience
txid = priv[:32]
@ -66,7 +65,7 @@ def test_mk_shuffled_tx():
# prepare two addresses for the outputs
pub = btc.privkey_to_pubkey(btc.Hash(b"priv") + b"\x01")
scriptPubKey = btc.CScript([btc.OP_0, btc.Hash160(pub)])
addr1 = btc.P2WPKHBitcoinAddress.from_scriptPubKey(scriptPubKey)
addr1 = btc.P2WPKHCoinAddress.from_scriptPubKey(scriptPubKey)
scriptPubKey_p2sh = scriptPubKey.to_p2sh_scriptPubKey()
addr2 = btc.CCoinAddress.from_scriptPubKey(scriptPubKey_p2sh)

5
jmclient/jmclient/client_protocol.py

@ -1,5 +1,4 @@
#! /usr/bin/env python
from future.utils import iteritems
from twisted.internet import protocol, reactor, task
from twisted.internet.error import (ConnectionLost, ConnectionAborted,
ConnectionClosed, ConnectionDone)
@ -15,7 +14,7 @@ import hashlib
import os
import sys
from jmbase import (get_log, EXIT_FAILURE, hextobin, bintohex,
utxo_to_utxostr, dictchanger)
utxo_to_utxostr)
from jmclient import (jm_single, get_irc_mchannels,
RegtestBitcoinCoreInterface)
import jmbitcoin as btc
@ -303,7 +302,7 @@ class JMMakerClientProtocol(JMClientProtocol):
return {"accepted": True}
def tx_match(self, txd):
for k,v in iteritems(self.finalized_offers):
for k,v in self.finalized_offers.items():
# Tx considered defined by its output set
if v["txd"].vout == txd.vout:
offerinfo = v

5
jmclient/jmclient/commitment_utils.py

@ -1,10 +1,7 @@
import sys
import jmbitcoin as btc
from jmbase import jmprint
from jmclient import (jm_single, get_p2pk_vbyte, get_p2sh_vbyte,
BTCEngine, TYPE_P2PKH, TYPE_P2SH_P2WPKH,
BTC_P2PKH, BTC_P2SH_P2WPKH)
from jmclient import jm_single, BTCEngine, BTC_P2PKH, BTC_P2SH_P2WPKH
from jmbase.support import EXIT_FAILURE, utxostr_to_utxo

4
jmclient/jmclient/configure.py

@ -379,13 +379,13 @@ def validate_address(addr):
try:
# automatically respects the network
# as set in btc.select_chain_params(...)
x = btc.CCoinAddress(addr)
dummyaddr = btc.CCoinAddress(addr)
except Exception as e:
return False, repr(e)
# additional check necessary because python-bitcointx
# does not check hash length on p2sh construction.
try:
x.to_scriptPubKey()
dummyaddr.to_scriptPubKey()
except Exception as e:
return False, repr(e)
return True, "address validated"

10
jmclient/jmclient/cryptoengine.py

@ -1,11 +1,11 @@
from binascii import hexlify, unhexlify
from collections import OrderedDict
import struct
import jmbitcoin as btc
from .configure import get_network, jm_single
from jmbase import bintohex
from .configure import get_network
#NOTE: before fidelity bonds and watchonly wallet, each of these types corresponded
# to one wallet type and one engine, not anymore
@ -31,7 +31,7 @@ def detect_script_type(script_str):
script = btc.CScript(script_str)
if not script.is_valid():
raise EngineError("Unknown script type for script '{}'"
.format(hexlify(script_str)))
.format(bintohex(script_str)))
if script.is_p2pkh():
return TYPE_P2PKH
elif script.is_p2sh():
@ -42,7 +42,7 @@ def detect_script_type(script_str):
elif script.is_witness_v0_keyhash():
return TYPE_P2WPKH
raise EngineError("Unknown script type for script '{}'"
.format(hexlify(script_str)))
.format(bintohex(script_str)))
class classproperty(object):
"""

3
jmclient/jmclient/electruminterface.py

@ -1,4 +1,3 @@
from future.utils import iteritems
import jmbitcoin as btc
import json
import queue as Queue
@ -332,7 +331,7 @@ class ElectrumInterface(BlockchainInterface):
for m in range(wallet.max_mixdepth):
for fc in [0, 1]:
branch_list = []
for k, v in iteritems(self.temp_addr_history[m][fc]):
for k, v in self.temp_addr_history[m][fc].items():
if k == "finished":
continue
if v["used"]:

8
jmclient/jmclient/maker.py

@ -1,5 +1,4 @@
#! /usr/bin/env python
from future.utils import iteritems
import base64
import pprint
import random
@ -7,8 +6,7 @@ import sys
import abc
import jmbitcoin as btc
from jmbase import (bintohex, hextobin, hexbin,
get_log, EXIT_SUCCESS, EXIT_FAILURE)
from jmbase import bintohex, hexbin, get_log, EXIT_SUCCESS, EXIT_FAILURE
from jmclient.wallet import estimate_tx_fee, compute_tx_locktime
from jmclient.wallet_service import WalletService
from jmclient.configure import jm_single
@ -470,7 +468,7 @@ class P2EPMaker(Maker):
[x[1] for x in utxo.values()])
total_sender_input = 0
for i, u in iteritems(utxo):
for i, u in utxo.items():
if utxo_data[i] is None:
return (False, "Proposed transaction contains invalid utxos")
total_sender_input += utxo_data[i]["value"]
@ -505,7 +503,7 @@ class P2EPMaker(Maker):
# Manual verification of the transaction signatures.
# TODO handle native segwit properly
for i, u in iteritems(utxo):
for i, u in utxo.items():
if not btc.verify_tx_input(tx, i,
tx.vin[i].scriptSig,
btc.CScript(utxo_data[i]["script"]),

1
jmclient/jmclient/podle.py

@ -5,7 +5,6 @@ import os
import sys
import hashlib
import json
import binascii
import struct
from pprint import pformat
from jmbase import jmprint

6
jmclient/jmclient/snicker_receiver.py

@ -1,13 +1,9 @@
#! /usr/bin/env python
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from builtins import * # noqa: F401
import sys
import binascii
import jmbitcoin as btc
from jmclient.configure import get_p2pk_vbyte, jm_single
from jmclient.configure import jm_single
from jmbase import (get_log, EXIT_FAILURE, utxo_to_utxostr,
bintohex, hextobin)

6
jmclient/jmclient/storage.py

@ -1,5 +1,3 @@
from future.utils import native
import os
import shutil
import atexit
@ -253,7 +251,7 @@ class Storage(object):
def _encrypt(self, data, iv):
encrypter = pyaes.Encrypter(
pyaes.AESModeOfOperationCBC(self._hash.hash, iv=native(iv)))
pyaes.AESModeOfOperationCBC(self._hash.hash, iv=iv))
enc_data = encrypter.feed(self.MAGIC_DETECT_ENC + data)
enc_data += encrypter.feed()
@ -261,7 +259,7 @@ class Storage(object):
def _decrypt(self, data, iv):
decrypter = pyaes.Decrypter(
pyaes.AESModeOfOperationCBC(self._hash.hash, iv=native(iv)))
pyaes.AESModeOfOperationCBC(self._hash.hash, iv=iv))
try:
dec_data = decrypter.feed(data)
dec_data += decrypter.feed()

23
jmclient/jmclient/taker.py

@ -1,5 +1,4 @@
#! /usr/bin/env python
from future.utils import iteritems
import base64
import pprint
@ -8,11 +7,11 @@ from twisted.internet import reactor, task
import jmbitcoin as btc
from jmclient.configure import jm_single, validate_address
from jmbase import get_log, hextobin, bintohex, hexbin
from jmbase import get_log, bintohex, hexbin
from jmclient.support import (calc_cj_fee, weighted_order_choose, choose_orders,
choose_sweep_orders)
from jmclient.wallet import estimate_tx_fee, compute_tx_locktime
from jmclient.podle import generate_podle, get_podle_commitments, PoDLE
from jmclient.podle import generate_podle, get_podle_commitments
from jmclient.wallet_service import WalletService
from .output import generate_podle_error_string
from .cryptoengine import EngineError
@ -354,7 +353,7 @@ class Taker(object):
rejected_counterparties = []
#Need to authorize against the btc pubkey first.
for nick, nickdata in iteritems(ioauth_data):
for nick, nickdata in ioauth_data.items():
utxo_list, auth_pub, cj_addr, change_addr, btc_sig, maker_pk = nickdata
if not self.auth_counterparty(btc_sig, auth_pub, maker_pk):
jlog.debug(
@ -374,7 +373,7 @@ class Taker(object):
self.maker_utxo_data = {}
for nick, nickdata in iteritems(ioauth_data):
for nick, nickdata in ioauth_data.items():
utxo_list, auth_pub, cj_addr, change_addr, _, _ = nickdata
utxo_data = jm_single().bc_interface.query_utxo_set(utxo_list)
self.utxos[nick] = utxo_list
@ -452,8 +451,7 @@ class Taker(object):
#used to track return of signatures for phase 2
self.nonrespondants = list(self.maker_utxo_data.keys())
my_total_in = sum([va['value'] for u, va in iteritems(self.input_utxos)
])
my_total_in = sum([va['value'] for u, va in self.input_utxos.items()])
if self.my_change_addr:
#Estimate fee per choice of next/3/6 blocks targetting.
estimated_fee = estimate_tx_fee(
@ -559,7 +557,7 @@ class Taker(object):
utxo_data = jm_single().bc_interface.query_utxo_set([x[
1] for x in utxo.values()])
# insert signatures
for i, u in iteritems(utxo):
for i, u in utxo.items():
if utxo_data[i] is None:
continue
# Check if the sender included the scriptCode in the sig message;
@ -698,7 +696,7 @@ class Taker(object):
new_utxos, too_old, too_small = filter_by_coin_age_amt(list(utxos.keys()),
age, amt)
new_utxos_dict = {k: v for k, v in utxos.items() if k in new_utxos}
for k, v in iteritems(new_utxos_dict):
for k, v in new_utxos_dict.items():
addr = self.wallet_service.script_to_addr(v["script"])
priv = self.wallet_service.get_key_from_addr(addr)
if priv: #can be null from create-unsigned
@ -831,7 +829,8 @@ class Taker(object):
self.on_finished_callback(False, fromtx=True)
else:
if nick_to_use:
return (nick_to_use, tx)
# TODO option not currently functional
return (nick_to_use, self.latest_tx.serialize())
#if push was not successful, return None
def self_sign_and_push(self):
@ -985,7 +984,7 @@ class P2EPTaker(Taker):
# use output destination self.my_cj_addr and use amount self.amount
self.outputs.append({'address': self.my_cj_addr,
'value': self.cjamount})
my_total_in = sum([va['value'] for u, va in iteritems(self.input_utxos)])
my_total_in = sum([va['value'] for u, va in self.input_utxos.items()])
# estimate the fee for the version of the transaction which is
# not coinjoined:
est_fee = estimate_tx_fee(len(self.input_utxos), 2,
@ -1137,7 +1136,7 @@ class P2EPTaker(Taker):
# Next we'll verify each of the counterparty's inputs,
# while at the same time gathering the total they spent.
total_receiver_input = 0
for i, u in iteritems(retrieve_utxos):
for i, u in retrieve_utxos.items():
if utxo_data[i] is None:
return (False, "Proposed transaction contains invalid utxos")
total_receiver_input += utxo_data[i]["value"]

16
jmclient/jmclient/taker_utils.py

@ -1,4 +1,3 @@
from future.utils import iteritems
import logging
import pprint
import os
@ -81,8 +80,7 @@ def direct_send(wallet_service, amount, mixdepth, destination, answeryes=False,
log.error(
"There are no available utxos in mixdepth: " + str(mixdepth) + ", quitting.")
return
total_inputs_val = sum([va['value'] for u, va in iteritems(utxos)])
total_inputs_val = sum([va['value'] for u, va in utxos.items()])
if is_burn_destination(destination):
if len(utxos) > 1:
@ -116,7 +114,7 @@ def direct_send(wallet_service, amount, mixdepth, destination, answeryes=False,
fee_est = estimate_tx_fee(len(utxos), 2, txtype=txtype)
else:
fee_est = initial_fee_est
total_inputs_val = sum([va['value'] for u, va in iteritems(utxos)])
total_inputs_val = sum([va['value'] for u, va in utxos.items()])
changeval = total_inputs_val - fee_est - amount
outs = [{"value": amount, "address": destination}]
change_addr = wallet_service.get_internal_addr(mixdepth)
@ -193,16 +191,6 @@ def direct_send(wallet_service, amount, mixdepth, destination, answeryes=False,
txinfo = txid if not return_transaction else tx
return txinfo
def sign_tx(wallet_service, tx, utxos):
stx = deserialize(tx)
our_inputs = {}
for index, ins in enumerate(stx['ins']):
utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
script = wallet_service.addr_to_script(utxos[utxo]['address'])
amount = utxos[utxo]['value']
our_inputs[index] = (script, amount)
return wallet_service.sign_tx(stx, our_inputs)
def get_tumble_log(logsdir):
tumble_log = logging.getLogger('tumbler')
tumble_log.setLevel(logging.DEBUG)

28
jmclient/jmclient/wallet.py

@ -28,7 +28,7 @@ from .cryptoengine import TYPE_P2PKH, TYPE_P2SH_P2WPKH,\
from .support import get_random_bytes
from . import mn_encode, mn_decode
import jmbitcoin as btc
from jmbase import JM_WALLET_NAME_PREFIX, bintohex
from jmbase import JM_WALLET_NAME_PREFIX
"""
@ -998,23 +998,6 @@ class BaseWallet(object):
def __del__(self):
self.close()
class DummyKeyStore(btc.KeyStore):
@classmethod
def from_iterable(cls, iterable, **kwargs):
kstore = cls(**kwargs)
for k in iterable:
kstore.add_key(k)
return kstore
def add_key(self, k):
if isinstance(k, btc.CKeyBase):
if k.pub.key_id in self._privkeys:
assert self._privkeys[k.pub.key_id] == k
else:
self._privkeys[k.pub.key_id] = k
else:
raise ValueError('object supplied to add_key is of unrecognized type')
class PSBTWalletMixin(object):
"""
Mixin for BaseWallet to provide BIP174
@ -1062,7 +1045,7 @@ class PSBTWalletMixin(object):
assert False, "invalid spent output type passed into PSBT creator"
# we now insert redeemscripts where that is possible and necessary:
for i, txinput in enumerate(new_psbt.inputs):
if isinstance(txinput.utxo, btc.CMutableTxOut):
if isinstance(txinput.utxo, btc.CTxOut):
# witness
if txinput.utxo.scriptPubKey.is_witness_scriptpubkey():
# nothing needs inserting; the scriptSig is empty.
@ -1094,14 +1077,15 @@ class PSBTWalletMixin(object):
"""
try:
new_psbt = btc.PartiallySignedTransaction.from_binary(in_psbt)
except:
return None, "Unable to deserialize the PSBT object, invalid format."
except Exception as e:
return None, "Unable to deserialize binary PSBT, error: " + repr(e)
privkeys = []
for k, v in self._utxos._utxo.items():
for k2, v2 in v.items():
privkeys.append(self._get_priv_from_path(v2[0]))
jmckeys = list(btc.JMCKey(x[0][:-1]) for x in privkeys)
new_keystore = DummyKeyStore.from_iterable(jmckeys)
new_keystore = btc.KeyStore.from_iterable(jmckeys,
require_path_templates=False)
# for p2sh inputs that we want to sign, the redeem_script
# field must be populated by us, as the counterparty did not

5
jmclient/jmclient/wallet_service.py

@ -3,7 +3,6 @@
import collections
import time
import ast
import binascii
import sys
from decimal import Decimal
from copy import deepcopy
@ -16,8 +15,8 @@ from jmclient.output import fmt_tx_data
from jmclient.blockchaininterface import (INF_HEIGHT, BitcoinCoreInterface,
BitcoinCoreNoHistoryInterface)
from jmclient.wallet import FidelityBondMixin
from jmbase.support import jmprint, EXIT_SUCCESS, utxo_to_utxostr, bintohex, hextobin
from jmbitcoin import lx
from jmbase.support import jmprint, EXIT_SUCCESS, utxo_to_utxostr, hextobin
"""Wallet service

34
jmclient/jmclient/wallet_utils.py

@ -1,4 +1,3 @@
from future.utils import iteritems
import json
import os
import sys
@ -17,7 +16,7 @@ from jmclient import (get_network, WALLET_IMPLEMENTATIONS, Storage, podle,
is_native_segwit_mode, load_program_config, add_base_options, check_regtest)
from jmclient.wallet_service import WalletService
from jmbase.support import (get_password, jmprint, EXIT_FAILURE,
EXIT_ARGERROR, utxo_to_utxostr)
EXIT_ARGERROR, utxo_to_utxostr, hextobin)
from .cryptoengine import TYPE_P2PKH, TYPE_P2SH_P2WPKH, TYPE_P2WPKH, \
TYPE_SEGWIT_LEGACY_WALLET_FIDELITY_BONDS
@ -324,9 +323,8 @@ def get_tx_info(txid):
"""
rpctx = jm_single().bc_interface.get_transaction(txid)
txhex = str(rpctx['hex'])
txd = btc.deserialize(txhex)
output_script_values = {binascii.unhexlify(sv['script']): sv['value']
for sv in txd['outs']}
tx = btc.CMutableTransaction.deserialize(hextobin(txhex))
output_script_values = {x.scriptPubKey: x.nValue for x in tx.vout}
value_freq_list = sorted(
Counter(output_script_values.values()).most_common(),
key=lambda x: -x[1])
@ -338,7 +336,7 @@ def get_tx_info(txid):
cj_amount = value_freq_list[0][0]
cj_n = value_freq_list[0][1]
return is_coinjoin, cj_amount, cj_n, output_script_values,\
rpctx.get('blocktime', 0), txd
rpctx.get('blocktime', 0), tx
def get_imported_privkey_branch(wallet_service, m, showprivkey):
@ -383,7 +381,7 @@ def wallet_showutxos(wallet, showprivkey):
unsp[us]['privkey'] = wallet.get_wif_path(av['path'])
used_commitments, external_commitments = podle.get_podle_commitments()
for u, ec in iteritems(external_commitments):
for u, ec in external_commitments.items():
success, us = utxo_to_utxostr(u)
assert success
tries = podle.get_podle_tries(utxo=u, max_tries=max_tries,
@ -404,7 +402,7 @@ def wallet_display(wallet_service, showprivkey, displayall=False,
def get_addr_status(addr_path, utxos, is_new, is_internal):
addr_balance = 0
status = []
for utxo, utxodata in iteritems(utxos):
for utxo, utxodata in utxos.items():
if addr_path != utxodata['path']:
continue
addr_balance += utxodata['value']
@ -415,7 +413,7 @@ def wallet_display(wallet_service, showprivkey, displayall=False,
# to bci
if jm_single().bc_interface.__class__ == BitcoinCoreInterface:
is_coinjoin, cj_amount, cj_n = \
get_tx_info(binascii.hexlify(utxo[0]).decode('ascii'))[:3]
get_tx_info(utxo[0])[:3]
if is_coinjoin and utxodata['value'] == cj_amount:
status.append('cj-out')
elif is_coinjoin:
@ -774,7 +772,7 @@ def wallet_fetch_history(wallet, options):
tx_number = 0
for tx in txes:
is_coinjoin, cj_amount, cj_n, output_script_values, blocktime, txd =\
get_tx_info(tx['txid'])
get_tx_info(hextobin(tx['txid']))
# unconfirmed transactions don't have blocktime, get_tx_info() returns
# 0 in that case
@ -784,21 +782,21 @@ def wallet_fetch_history(wallet, options):
output_script_values.keys())
rpc_inputs = []
for ins in txd['ins']:
for ins in txd.vin:
wallet_tx = jm_single().bc_interface.get_transaction(
ins['outpoint']['hash'])
ins.prevout.hash[::-1])
if wallet_tx is None:
continue
input_dict = btc.deserialize(str(wallet_tx['hex']))['outs'][ins[
'outpoint']['index']]
inp = btc.CMutableTransaction.deserialize(hextobin(
wallet_tx['hex'])).vout[ins.prevout.n]
input_dict = {"script": inp.scriptPubKey, "value": inp.nValue}
rpc_inputs.append(input_dict)
rpc_input_scripts = set(binascii.unhexlify(ind['script'])
for ind in rpc_inputs)
rpc_input_scripts = set(ind['script'] for ind in rpc_inputs)
our_input_scripts = wallet_script_set.intersection(rpc_input_scripts)
our_input_values = [
ind['value'] for ind in rpc_inputs
if binascii.unhexlify(ind['script']) in our_input_scripts]
if ind['script'] in our_input_scripts]
our_input_value = sum(our_input_values)
utxos_consumed = len(our_input_values)
@ -866,7 +864,7 @@ def wallet_fetch_history(wallet, options):
amount = cj_amount
delta_balance = out_value - our_input_value
mixdepth_src = wallet.get_script_mixdepth(list(our_input_scripts)[0])
cj_script = list(set([a for a, v in iteritems(output_script_values)
cj_script = list(set([a for a, v in output_script_values.items()
if v == cj_amount]).intersection(our_output_scripts))[0]
mixdepth_dst = wallet.get_script_mixdepth(cj_script)
else:

7
jmclient/jmclient/yieldgenerator.py

@ -1,5 +1,4 @@
#! /usr/bin/env python
from future.utils import iteritems
import datetime
import os
@ -78,7 +77,7 @@ class YieldGeneratorBasic(YieldGenerator):
def create_my_orders(self):
mix_balance = self.get_available_mixdepths()
if len([b for m, b in iteritems(mix_balance) if b > 0]) == 0:
if len([b for m, b in mix_balance.items() if b > 0]) == 0:
jlog.error('do not have any coins left')
return []
@ -115,7 +114,7 @@ class YieldGeneratorBasic(YieldGenerator):
mix_balance = self.get_available_mixdepths()
filtered_mix_balance = {m: b
for m, b in iteritems(mix_balance)
for m, b in mix_balance.items()
if b >= total_amount}
if not filtered_mix_balance:
return None, None, None
@ -177,7 +176,7 @@ class YieldGeneratorBasic(YieldGenerator):
inputs. available is a mixdepth/balance dict of all the mixdepths
that can be chosen from, i.e. have enough balance. If there is no
suitable input, the function can return None to abort the order."""
available = sorted(iteritems(available), key=lambda entry: entry[0])
available = sorted(available.items(), key=lambda entry: entry[0])
return available[0][0]
def select_output_address(self, input_mixdepth, offer, amount):

5
jmclient/setup.py

@ -9,8 +9,7 @@ setup(name='joinmarketclient',
author_email='',
license='GPL',
packages=['jmclient'],
install_requires=['future', 'configparser;python_version<"3.2"',
'joinmarketbase==0.7.0dev', 'mnemonic', 'argon2_cffi',
install_requires=['joinmarketbase==0.7.0dev', 'mnemonic', 'argon2_cffi',
'bencoder.pyx>=2.0.0', 'pyaes'],
python_requires='>=3.3',
python_requires='>=3.6',
zip_safe=False)

5
jmclient/test/commontest.py

@ -6,12 +6,11 @@ import binascii
import random
from decimal import Decimal
from jmbase import (get_log, hextobin, utxostr_to_utxo,
utxo_to_utxostr, listchanger, dictchanger)
from jmbase import (get_log, hextobin, dictchanger)
from jmclient import (
jm_single, open_test_wallet_maybe, estimate_tx_fee,
BlockchainInterface, get_p2sh_vbyte, BIP32Wallet,
BlockchainInterface, BIP32Wallet,
SegwitLegacyWallet, WalletService, BTC_P2SH_P2WPKH)
from jmbase.support import chunks
import jmbitcoin as btc

2
jmclient/test/test_client_protocol.py

@ -1,7 +1,7 @@
#! /usr/bin/env python
'''test client-protocol interfacae.'''
from jmbase import get_log, bintohex, hextobin
from jmbase import get_log, bintohex
from jmbase.commands import *
from jmclient import load_test_config, Taker,\
JMClientProtocolFactory, jm_single, Maker, WalletService

2
jmclient/test/test_coinjoin.py

@ -9,7 +9,7 @@ import pytest
import copy
from twisted.internet import reactor
from jmbase import get_log, hextobin, bintohex
from jmbase import get_log, hextobin
from jmclient import load_test_config, jm_single,\
YieldGeneratorBasic, Taker, LegacyWallet, SegwitLegacyWallet,\
NO_ROUNDING

3
jmclient/test/test_maker.py

@ -1,8 +1,7 @@
#!/usr/bin/env python
import jmbitcoin as btc
from jmclient import Maker, get_p2sh_vbyte, get_p2pk_vbyte, \
load_test_config, jm_single, WalletService
from jmclient import Maker, load_test_config, jm_single, WalletService
import jmclient
from commontest import DummyBlockchainInterface
from test_taker import DummyWallet

2
jmclient/test/test_payjoin.py

@ -11,7 +11,7 @@ from jmbase import get_log
from jmclient import cryptoengine
from jmclient import (load_test_config, jm_single,
P2EPMaker, P2EPTaker,
LegacyWallet, SegwitLegacyWallet, SegwitWallet)
SegwitLegacyWallet, SegwitWallet)
from commontest import make_wallets
from test_coinjoin import make_wallets_to_list, create_orderbook, sync_wallets

1
jmclient/test/test_podle.py

@ -2,7 +2,6 @@
'''Tests of Proof of discrete log equivalence commitments.'''
import os
import jmbitcoin as bitcoin
import binascii
import struct
import json
import pytest

8
jmclient/test/test_privkeys.py

@ -2,10 +2,8 @@
'''Public and private key validity and formatting tests.'''
import jmbitcoin as btc
from jmclient import (BTCEngine, BTC_P2PKH, BTC_P2SH_P2WPKH,
jm_single, load_test_config)
import binascii
import struct
from jmbase import hextobin
from jmclient import BTCEngine, jm_single, load_test_config
import json
import pytest
import os
@ -76,7 +74,7 @@ def test_wif_privkeys_valid(setup_keys):
# we only handle compressed keys
continue
from_wif_key, keytype = BTCEngine.wif_to_privkey(key)
expected_key = binascii.unhexlify(hex_key) + b"\x01"
expected_key = hextobin(hex_key) + b"\x01"
assert from_wif_key == expected_key, "Incorrect key decoding: " + \
str(from_wif_key) + ", should be: " + str(expected_key)
jm_single().config.set("BLOCKCHAIN", "network", "testnet")

5
jmclient/test/test_psbt_wallet.py

@ -6,15 +6,12 @@
BIP174 are tested there, not here.
'''
import time
import binascii
import struct
import copy
from commontest import make_wallets, dummy_accept_callback, dummy_info_callback
import jmbitcoin as bitcoin
import pytest
from jmbase import get_log, bintohex, hextobin
from jmbase import get_log, bintohex
from jmclient import (load_test_config, jm_single, direct_send,
SegwitLegacyWallet, SegwitWallet, LegacyWallet)

14
jmclient/test/test_snicker.py

@ -1,18 +1,14 @@
#! /usr/bin/env python
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from builtins import * # noqa: F401
'''Test of unusual transaction types creation and push to
network to check validity.'''
'''Test of SNICKER functionality using Joinmarket
wallets as defined in jmclient.wallet.'''
import binascii
from commontest import make_wallets, dummy_accept_callback, dummy_info_callback
import jmbitcoin as btc
import pytest
from jmbase import get_log, bintohex, hextobin
from jmclient import (load_test_config, jm_single,
estimate_tx_fee, SNICKERReceiver, direct_send)
from jmbase import get_log, bintohex
from jmclient import (load_test_config, estimate_tx_fee, SNICKERReceiver,
direct_send)
log = get_log()

3
jmclient/test/test_taker.py

@ -10,8 +10,7 @@ import pytest
import json
import struct
from base64 import b64encode
from jmbase import (utxostr_to_utxo, utxo_to_utxostr, hextobin,
dictchanger, listchanger)
from jmbase import utxostr_to_utxo, hextobin
from jmclient import load_test_config, jm_single, set_commitment_file,\
get_commitment_file, SegwitLegacyWallet, Taker, VolatileStorage,\
get_network, WalletService, NO_ROUNDING, BTC_P2PKH

5
jmclient/test/test_tx_creation.py

@ -5,8 +5,6 @@
p2(w)sh tests, these have been removed since Joinmarket
does not use this feature.'''
import time
import binascii
import struct
from binascii import unhexlify
from commontest import make_wallets, make_sign_and_push, ensure_bip65_activated
@ -14,8 +12,7 @@ from commontest import make_wallets, make_sign_and_push, ensure_bip65_activated
import jmbitcoin as bitcoin
import pytest
from jmbase import get_log
from jmclient import load_test_config, jm_single,\
get_p2pk_vbyte
from jmclient import load_test_config, jm_single
log = get_log()
#just a random selection of pubkeys for receiving multisigs;

3
jmclient/test/test_wallet.py

@ -7,8 +7,7 @@ from binascii import hexlify, unhexlify
import pytest
import jmbitcoin as btc
from commontest import ensure_bip65_activated
from jmbase import (get_log, utxostr_to_utxo, utxo_to_utxostr,
hextobin, bintohex)
from jmbase import get_log, hextobin
from jmclient import load_test_config, jm_single, \
SegwitLegacyWallet,BIP32Wallet, BIP49Wallet, LegacyWallet,\
VolatileStorage, get_network, cryptoengine, WalletError,\

1
jmclient/test/test_wallets.py

@ -9,7 +9,6 @@ import json
import pytest
from jmbase import get_log, hextobin
import jmbitcoin as btc
from jmclient import (
load_test_config, jm_single,
estimate_tx_fee, BitcoinCoreInterface, Mnemonic)

3
jmdaemon/jmdaemon/daemon_protocol.py

@ -1,5 +1,4 @@
#! /usr/bin/env python
from future.utils import iteritems
from .message_channel import MessageChannelCollection
from .orderbookwatch import OrderbookWatch
@ -239,7 +238,7 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
#Reset utxo data to null for this new transaction
self.ioauth_data = {}
self.active_orders = json.loads(filled_offers)
for nick, offer_dict in iteritems(self.active_orders):
for nick, offer_dict in self.active_orders.items():
offer_fill_msg = " ".join([str(offer_dict["oid"]), str(amount),
self.kp.hex_pk().decode('ascii'), str(commitment)])
self.mcc.prepare_privmsg(nick, "fill", offer_fill_msg)

1
jmdaemon/jmdaemon/irc.py

@ -17,7 +17,6 @@ def wlog(*x):
"""Simplifier to add lists to the debug log
"""
def conv(s):
# note: this only works because of the future package
if isinstance(s, str):
return s
elif isinstance(s, bytes):

7
jmdaemon/jmdaemon/message_channel.py

@ -1,5 +1,4 @@
#! /usr/bin/env python
from future.utils import iteritems
import abc
import base64
import binascii
@ -334,7 +333,7 @@ class MessageChannelCollection(object):
"""
for mc in self.available_channels():
filtered_nick_order_dict = {k: v
for k, v in iteritems(nick_order_dict)
for k, v in nick_order_dict.items()
if mc == self.active_channels[k]}
mc.fill_orders(filtered_nick_order_dict, cj_amount, taker_pubkey,
commitment)
@ -370,7 +369,7 @@ class MessageChannelCollection(object):
tx_nick_sets[self.active_channels[nick]] = [nick]
else:
tx_nick_sets[self.active_channels[nick]].append(nick)
for mc, nl in iteritems(tx_nick_sets):
for mc, nl in tx_nick_sets.items():
self.prepare_send_tx(mc, nl, txhex)
def prepare_send_tx(self, mc, nick_list, txhex):
@ -824,7 +823,7 @@ class MessageChannel(object):
# Taker callbacks
def fill_orders(self, nick_order_dict, cj_amount, taker_pubkey, commitment):
for c, order in iteritems(nick_order_dict):
for c, order in nick_order_dict.items():
msg = str(order['oid']) + ' ' + str(cj_amount) + ' ' + taker_pubkey
msg += ' ' + commitment
self.privmsg(c, 'fill', msg)

4
jmdaemon/setup.py

@ -9,6 +9,6 @@ setup(name='joinmarketdaemon',
author_email='',
license='GPL',
packages=['jmdaemon'],
install_requires=['future', 'txtorcon', 'pyopenssl', 'libnacl', 'joinmarketbase==0.7.0dev'],
python_requires='>=3.3',
install_requires=['txtorcon', 'pyopenssl', 'libnacl', 'joinmarketbase==0.7.0dev'],
python_requires='>=3.6',
zip_safe=False)

3
jmdaemon/test/test_daemon_protocol.py

@ -1,5 +1,4 @@
#! /usr/bin/env python
from future.utils import iteritems
'''test daemon-protocol interfacae.'''
from jmdaemon import MessageChannelCollection
@ -254,7 +253,7 @@ class JMDaemonTestServerProtocol(JMDaemonServerProtocol):
"!push abcd abc def", "3", "4",
str(list(tmpfo.keys())[0]), 6, 7, self.mcc.mchannels[0].hostid)
#send "valid" onpubkey, onioauth messages
for k, v in iteritems(tmpfo):
for k, v in tmpfo.items():
reactor.callLater(1, self.on_pubkey, k, dummypub)
reactor.callLater(2, self.on_ioauth, k, ['a', 'b'], "auth_pub",
"cj_addr", "change_addr", "btc_sig")

5
scripts/add-utxo.py

@ -11,10 +11,9 @@ import os
import json
import binascii
from pprint import pformat
from optparse import OptionParser
import jmbitcoin as btc
from jmclient import load_program_config, jm_single, get_p2pk_vbyte,\
from jmclient import load_program_config, jm_single,\
open_wallet, WalletService, add_external_commitments, update_commitments,\
PoDLE, get_podle_commitments, get_utxo_info, validate_utxo_data, quit,\
get_wallet_path, add_base_options, BTCEngine, BTC_P2SH_P2WPKH

2
scripts/joinmarket-qt.py

@ -66,7 +66,7 @@ JM_GUI_VERSION = '15dev'
from jmbase import get_log
from jmbase.support import DUST_THRESHOLD, EXIT_FAILURE, JM_CORE_VERSION
from jmclient import load_program_config, get_network, update_persist_config,\
open_test_wallet_maybe, get_wallet_path, get_p2sh_vbyte, get_p2pk_vbyte,\
open_test_wallet_maybe, get_wallet_path,\
jm_single, validate_address, weighted_order_choose, Taker,\
JMClientProtocolFactory, start_reactor, get_schedule, schedule_to_text,\
get_blockchain_interface_instance, direct_send, WalletService,\

5
scripts/sendtomany.py

@ -10,9 +10,8 @@ from optparse import OptionParser
import jmbitcoin as btc
from jmbase import get_log, jmprint, bintohex, utxostr_to_utxo
from jmclient import load_program_config, estimate_tx_fee, jm_single,\
get_p2pk_vbyte, validate_address, get_utxo_info, add_base_options,\
validate_utxo_data, quit, BTCEngine, BTC_P2SH_P2WPKH, BTC_P2PKH
validate_address, get_utxo_info, add_base_options,\
validate_utxo_data, quit, BTCEngine
log = get_log()

11
test/test_segwit.py

@ -1,13 +1,12 @@
#! /usr/bin/env python
'''Test creation of segwit transactions.'''
import binascii
import json
from common import make_wallets
from pprint import pformat
import jmbitcoin as btc
import pytest
from jmbase import get_log, hextobin, bintohex
from jmbase import get_log, hextobin
from jmclient import load_test_config, jm_single, LegacyWallet
log = get_log()
@ -25,14 +24,6 @@ def test_segwit_valid_txs(setup_segwit):
#TODO use bcinterface to decoderawtransaction
#and compare the json values
def binarize_tx(tx):
for o in tx['outs']:
o['script'] = binascii.unhexlify(o['script'])
for i in tx['ins']:
i['outpoint']['hash'] = binascii.unhexlify(i['outpoint']['hash'])
@pytest.mark.parametrize(
"wallet_structure, in_amt, amount, segwit_amt, segwit_ins, o_ins", [
([[1, 0, 0, 0, 0]], 1, 1000000, 1, [0, 1, 2], []),

Loading…
Cancel
Save