mirror of
https://github.com/JoinMarket-Org/joinmarket-clientserver.git
synced 2026-08-14 12:43:38 +02:00
Remove btc.py
Previous to this commit, the jmbitcoin package was accessed via a file in jmclient `btc.py` which was originally added as an interface to allow the client to use a non-jmbitcoin package to provide the implementation; while this idea is useful, the way it was implemented was not, moreover it is not currently used and contained duplicated code that was unmanaged. Also, the original usage of this was only by the electrum plugin, which has currently been abandoned. This simplifies the code and avoids spurious error messages. Note that most of the changes are a result of pulling the logging function directly from the jmbase package instead of indirectly via this interface (which was unnecessary and not connected with jmbitcoin).
This commit is contained in:
parent
5d6825bfb1
commit
54618e61da
37 changed files with 64 additions and 505 deletions
|
|
@ -13,6 +13,9 @@ import coincurve as secp256k1
|
|||
#Required only for PoDLE calculation:
|
||||
N = 115792089237316195423570985008687907852837564279074904382605163141518161494337
|
||||
|
||||
BTC_P2PK_VBYTE = {"mainnet": b'\x00', "testnet": b'\x6f'}
|
||||
BTC_P2SH_VBYTE = {"mainnet": b'\x05', "testnet": b'\xc4'}
|
||||
|
||||
#Standard prefix for Bitcoin message signing.
|
||||
BITCOIN_MESSAGE_MAGIC = b'\x18' + b'Bitcoin Signed Message:\n'
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,6 @@ from builtins import *
|
|||
|
||||
import logging
|
||||
|
||||
#Full joinmarket uses its own bitcoin module;
|
||||
#other implementations (like wallet plugins)
|
||||
#can optionally include their own, which must
|
||||
#be implemented as an interface in btc.py
|
||||
from .btc import *
|
||||
|
||||
from .support import (calc_cj_fee, choose_sweep_orders, choose_orders,
|
||||
cheapest_order_choose, weighted_order_choose,
|
||||
rand_norm_array, rand_pow_array, rand_exp_array, select,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ from copy import deepcopy
|
|||
from decimal import Decimal
|
||||
from twisted.internet import reactor, task
|
||||
|
||||
from . import btc
|
||||
import jmbitcoin as btc
|
||||
|
||||
from jmclient.jsonrpc import JsonRpcConnectionError, JsonRpcError
|
||||
from jmclient.configure import get_p2pk_vbyte, jm_single
|
||||
|
|
|
|||
|
|
@ -1,458 +0,0 @@
|
|||
"""Module to support bitcoin operations using a
|
||||
different codebase than joinmarket's own.
|
||||
"""
|
||||
from __future__ import (absolute_import, division,
|
||||
print_function, unicode_literals)
|
||||
from builtins import *
|
||||
#Protocol constants
|
||||
BTC_P2PK_VBYTE = {"mainnet": b'\x00', "testnet": b'\x6f'}
|
||||
BTC_P2SH_VBYTE = {"mainnet": b'\x05', "testnet": b'\xc4'}
|
||||
PODLE_COMMIT_FILE = None
|
||||
|
||||
from jmbase.support import get_log
|
||||
log = get_log()
|
||||
|
||||
#Required only for PoDLE calculation:
|
||||
N = 115792089237316195423570985008687907852837564279074904382605163141518161494337
|
||||
|
||||
interface = "joinmarket-joinmarket"
|
||||
|
||||
try:
|
||||
from jmbitcoin import *
|
||||
bjm = True
|
||||
except ImportError:
|
||||
#TODO figure out the right flexibility structure
|
||||
|
||||
interface = "joinmarket-electrum"
|
||||
|
||||
if interface != "joinmarket-electrum":
|
||||
raise NotImplementedError
|
||||
|
||||
not_supported_string = "not supported by: " + interface
|
||||
|
||||
# Base switching
|
||||
code_strings = {
|
||||
2: '01',
|
||||
10: '0123456789',
|
||||
16: '0123456789abcdef',
|
||||
32: 'abcdefghijklmnopqrstuvwxyz234567',
|
||||
58: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
|
||||
256: ''.join([chr(x) for x in range(256)])
|
||||
}
|
||||
def get_code_string(base):
|
||||
if base in code_strings:
|
||||
return code_strings[base]
|
||||
else:
|
||||
raise ValueError("Invalid base!")
|
||||
|
||||
def encode(val, base, minlen=0):
|
||||
base, minlen = int(base), int(minlen)
|
||||
code_string = get_code_string(base)
|
||||
result = ""
|
||||
while val > 0:
|
||||
result = code_string[val % base] + result
|
||||
val //= base
|
||||
return code_string[0] * max(minlen - len(result), 0) + result
|
||||
|
||||
def decode(string, base):
|
||||
base = int(base)
|
||||
code_string = get_code_string(base)
|
||||
result = 0
|
||||
if base == 16:
|
||||
string = string.lower()
|
||||
while len(string) > 0:
|
||||
result *= base
|
||||
result += code_string.find(string[0])
|
||||
string = string[1:]
|
||||
return result
|
||||
|
||||
#Electrum specific code starts here
|
||||
import electrum.bitcoin as ebt
|
||||
import electrum.transaction as etr
|
||||
from ecdsa.ecdsa import point_is_valid
|
||||
from ecdsa.util import string_to_number, sigdecode_der, sigencode_der
|
||||
from ecdsa import VerifyingKey, BadSignatureError, BadDigestError
|
||||
from ecdsa.curves import SECP256k1
|
||||
from ecdsa.numbertheory import square_root_mod_prime
|
||||
from ecdsa.ellipticcurve import Point
|
||||
|
||||
class PPubKey(object):
|
||||
def __init__(self, serP):
|
||||
self._point = ebt.ser_to_point(serP)
|
||||
def serialize(self):
|
||||
return ebt.point_to_ser(self._point)
|
||||
|
||||
class PPrivKey(object):
|
||||
def __init__(self, scalar):
|
||||
self._privkey = ebt.EC_KEY(scalar)
|
||||
self.private_key = scalar
|
||||
self.pubkey = PPubKey(binascii.unhexlify(
|
||||
self._privkey.get_public_key()))
|
||||
|
||||
podle_PublicKey_class = PPubKey
|
||||
podle_PrivateKey_class = PPrivKey
|
||||
|
||||
def podle_PublicKey(P):
|
||||
return PPubKey(P)
|
||||
|
||||
def podle_PrivateKey(priv):
|
||||
return PPrivKey(priv)
|
||||
|
||||
def multiply(s, pub, usehex, rawpub=True, return_serialized=True):
|
||||
"""s should be 32 byte scalar, pub should be of type
|
||||
podle_PublicKey_class
|
||||
"""
|
||||
if usehex:
|
||||
s = binascii.unhexlify(s)
|
||||
pub = binascii.unhexlify(pub)
|
||||
ppub = PPubKey(pub)
|
||||
p = ppub._point
|
||||
s_int = decode(s, 256)
|
||||
m = p * s_int
|
||||
r = PPubKey(ebt.point_to_ser(m))
|
||||
if return_serialized:
|
||||
return r.serialize()
|
||||
return r
|
||||
|
||||
def add_pubkeys(pubkeys, usehex):
|
||||
"""Pubkeys should be a list (for compatibility).
|
||||
"""
|
||||
#Not supporting more than 2 items for now, not needed.
|
||||
assert len(pubkeys) == 2
|
||||
if usehex:
|
||||
pubkeys = [binascii.unhexlify(x) for x in pubkeys]
|
||||
p1pt, p2pt = [ebt.ser_to_point(x) for x in pubkeys]
|
||||
sumpt = p1pt + p2pt
|
||||
return ebt.point_to_ser(sumpt)
|
||||
|
||||
def getG(compressed=True):
|
||||
scalar = "\x00"*31 + "\x01"
|
||||
return binascii.unhexlify(
|
||||
ebt.EC_KEY(scalar).get_public_key(compressed=compressed))
|
||||
|
||||
def sign(tx):
|
||||
#transaction signing is handled by the wallet for Electrum
|
||||
raise NotImplementedError("sign " + not_supported_string)
|
||||
|
||||
def get_version_byte(inp):
|
||||
leadingzbytes = len(re.match('^1*', inp).group(0))
|
||||
data = b'\x00' * leadingzbytes + b58check_to_bin(inp, version=True)
|
||||
return ord(data[0])
|
||||
|
||||
def b58check_to_bin(addr, version=False):
|
||||
"""optionally include the version byte for get_version_byte.
|
||||
"""
|
||||
if not version:
|
||||
return ebt.DecodeBase58Check(addr)[1:]
|
||||
else:
|
||||
return ebt.DecodeBase58Check(addr)
|
||||
|
||||
def address_to_script(addr):
|
||||
return etr.Transaction.pay_script(ebt.TYPE_ADDRESS, addr)
|
||||
|
||||
def script_to_address(script):
|
||||
bin_script = binascii.unhexlify(script)
|
||||
res = etr.get_address_from_output_script(bin_script)
|
||||
if not res[0] == ebt.TYPE_ADDRESS:
|
||||
raise ValueError("Invalid script for bitcoin address")
|
||||
return res[1]
|
||||
|
||||
def bin_dbl_sha256(x):
|
||||
return ebt.sha256(ebt.sha256(x))
|
||||
|
||||
def dbl_sha256(x):
|
||||
return binascii.hexlify(bin_dbl_sha256(x)).decode('ascii')
|
||||
|
||||
def verify_tx_input(tx, i, script, sig, pub):
|
||||
pub, sig, script = (binascii.unhexlify(x) for x in [pub, sig, script])
|
||||
t = etr.Transaction(tx)
|
||||
t.deserialize()
|
||||
#to prepare for verification (to do the txhash for modtx)
|
||||
#we need to have the "address" field set in the input.
|
||||
typ, addr = etr.get_address_from_output_script(script)
|
||||
if not typ == ebt.TYPE_ADDRESS:
|
||||
#Don't support non-p2sh, non-p2pkh for now
|
||||
log.debug("Invalid script")
|
||||
return False
|
||||
t.inputs()[i]["address"] = addr
|
||||
t.inputs()[i]["type"] = 'p2pkh'
|
||||
txforsig = etr.Hash(t.serialize_preimage(i).decode('hex'))
|
||||
ecdsa_pub = get_ecdsa_verifying_key(pub)
|
||||
if not ecdsa_pub:
|
||||
return False
|
||||
try:
|
||||
verified = ecdsa_pub.verify_digest(sig, txforsig,
|
||||
sigdecode = sigdecode_der)
|
||||
except (BadSignatureError, BadDigestError):
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_ecdsa_verifying_key(pub):
|
||||
#some shenanigans required to validate a transaction sig; see
|
||||
#python.ecdsa PR #54. This will be a lot simpler when that's merged.
|
||||
#https://github.com/warner/python-ecdsa/pull/54/files
|
||||
if not pub[0] in ["\x02", "\x03"]:
|
||||
log.debug("Invalid pubkey")
|
||||
return None
|
||||
is_even = pub.startswith('\x02')
|
||||
x = string_to_number(pub[1:])
|
||||
order = SECP256k1.order
|
||||
p = SECP256k1.curve.p()
|
||||
alpha = (pow(x, 3, p) + (SECP256k1.curve.a() * x) + SECP256k1.curve.b()) % p
|
||||
beta = square_root_mod_prime(alpha, p)
|
||||
if is_even == bool(beta & 1):
|
||||
y = p - beta
|
||||
else:
|
||||
y = beta
|
||||
if not point_is_valid(SECP256k1.generator, x, y):
|
||||
return None
|
||||
|
||||
point = Point(SECP256k1.curve, x, y, order)
|
||||
return VerifyingKey.from_public_point(point, SECP256k1,
|
||||
hashfunc=hashlib.sha256)
|
||||
|
||||
def ecdsa_verify(msg, sig, pub, usehex=True):
|
||||
sig = base64.b64decode(sig)
|
||||
if usehex:
|
||||
pub = binascii.unhexlify(pub)
|
||||
verif_key = get_ecdsa_verifying_key(pub)
|
||||
return verif_key.verify_digest(sig,
|
||||
ebt.Hash(ebt.msg_magic(msg)),
|
||||
sigdecode = sigdecode_der)
|
||||
|
||||
def ecdsa_sign(msg, priv, usehex=True):
|
||||
if usehex:
|
||||
priv = binascii.unhexlify(priv)
|
||||
compressed = False
|
||||
if len(priv) == 33 and priv[-1]=="\x01":
|
||||
compressed = True
|
||||
signkey = ebt.EC_KEY(priv[:32])
|
||||
private_key = ebt.MySigningKey.from_secret_exponent(signkey.secret,
|
||||
curve=SECP256k1)
|
||||
sig = private_key.sign_digest_deterministic(ebt.Hash(ebt.msg_magic(msg)),
|
||||
hashfunc=hashlib.sha256,
|
||||
sigencode = sigencode_der)
|
||||
return base64.b64encode(sig)
|
||||
|
||||
def serialize(txobj):
|
||||
#It is a rather chunky matter to re-use electrum.transaction code
|
||||
#to do serialization, it has a very different approach. Hence some
|
||||
#code duplication here with bitcoin-joinmarket. However we use the
|
||||
#number encoding functions from Electrum. Also, this is always in hex.
|
||||
o = []
|
||||
o.append(ebt.int_to_hex(txobj["version"], 4))
|
||||
o.append(ebt.var_int(len(txobj["ins"])))
|
||||
for inp in txobj["ins"]:
|
||||
binhash = binascii.unhexlify(inp["outpoint"]["hash"])
|
||||
binhash = binhash[::-1]
|
||||
o.append(binascii.hexlify(binhash).decode('ascii'))
|
||||
o.append(ebt.int_to_hex(inp["outpoint"]["index"], 4))
|
||||
o.append(ebt.var_int(len(inp["script"])/2) + inp["script"])
|
||||
o.append(ebt.int_to_hex(inp["sequence"], 4))
|
||||
o.append(ebt.var_int(len(txobj["outs"])))
|
||||
for out in txobj["outs"]:
|
||||
o.append(ebt.int_to_hex(out["value"], 8))
|
||||
o.append(ebt.var_int(len(out["script"])/2) + out["script"])
|
||||
o.append(ebt.int_to_hex(txobj["locktime"], 4))
|
||||
return ''.join(o)
|
||||
|
||||
def deserialize_script(scriptSig):
|
||||
#Assumes P2PKH scriptSig
|
||||
d = {}
|
||||
etr.parse_scriptSig(d, binascii.unhexlify(scriptSig))
|
||||
return (d["signatures"][0], d["pubkeys"][0])
|
||||
|
||||
def deserialize(txhex):
|
||||
t = etr.deserialize(txhex)
|
||||
#translation from Electrum deserialization
|
||||
#to pybitcointools form as used in joinmarket
|
||||
#pybitcointools structure:
|
||||
#obj = {"ins": [..], "outs": [..], "locktime": int}
|
||||
#where ins elements are:
|
||||
#{"outpoint": {"hash": bigendian32,"index": int},
|
||||
#"script": hex,"sequence": int}
|
||||
#and outs elements are:
|
||||
#{"script": hex, "value": int}
|
||||
#
|
||||
#while electrum.transaction.deserialize returns object
|
||||
#like:
|
||||
#{"version": int, "inputs": [..], "outputs": [..], "lockTime": int}
|
||||
obj = {}
|
||||
obj["version"] = t["version"]
|
||||
obj["locktime"] = t["lockTime"]
|
||||
obj["ins"] = []
|
||||
obj["outs"] = []
|
||||
for i in t["inputs"]:
|
||||
outpoint = {"hash": i["prevout_hash"], "index": i["prevout_n"]}
|
||||
scr = i["scriptSig"]
|
||||
sequence = i["sequence"]
|
||||
obj["ins"].append({"outpoint": outpoint, "script": scr, "sequence": sequence})
|
||||
for i in t["outputs"]:
|
||||
obj["outs"].append({"script": i["scriptPubKey"], "value": i["value"]})
|
||||
return obj
|
||||
|
||||
def privkey_to_pubkey(privkey, usehex=True):
|
||||
if usehex:
|
||||
privkey = binascii.unhexlify(privkey)
|
||||
if len(privkey)==33 and privkey[-1] == "\x01":
|
||||
compressed = True
|
||||
privkey = privkey[:32]
|
||||
elif len(privkey)==32:
|
||||
compressed=False
|
||||
else:
|
||||
raise ValueError("Invalid private key")
|
||||
sec = ebt.SecretToASecret(privkey, compressed=compressed)
|
||||
|
||||
retval = ebt.public_key_from_private_key(sec)
|
||||
if usehex:
|
||||
return retval
|
||||
return binascii.unhexlify(retval)
|
||||
|
||||
privtopub = privkey_to_pubkey
|
||||
|
||||
def privkey_to_address(privkey, magicbyte=0):
|
||||
pubkey = privkey_to_pubkey(privkey)
|
||||
return pubkey_to_address(pubkey, magicbyte)
|
||||
|
||||
privtoaddr = privkey_to_address
|
||||
|
||||
def pubkey_to_address(pub, magicbyte=0):
|
||||
h160 = ebt.hash_160(pub.decode('hex'))
|
||||
return ebt.hash_160_to_bc_address(h160, addrtype=magicbyte)
|
||||
|
||||
pubtoaddr = pubkey_to_address
|
||||
|
||||
def from_wif_privkey(privkey, vbyte=0):
|
||||
#converts a WIF compressed privkey to a hex private key
|
||||
return binascii.hexlify(ebt.ASecretToSecret(privkey)).decode('ascii')
|
||||
|
||||
def txhash(txhex):
|
||||
t = etr.Transaction(txhex)
|
||||
return t.txid()
|
||||
|
||||
#A simple copy-paste for now; move into support.py perhaps? TODO
|
||||
def estimate_tx_size(ins, outs, txtype='p2pkh'):
|
||||
'''Estimate transaction size.
|
||||
Assuming p2pkh:
|
||||
out: 8+1+3+2+20=34, in: 1+32+4+1+1+~73+1+1+33=147,
|
||||
ver:4,seq:4, +2 (len in,out)
|
||||
total ~= 34*len_out + 147*len_in + 10 (sig sizes vary slightly)
|
||||
'''
|
||||
if txtype == 'p2pkh':
|
||||
return 10 + ins * 147 + 34 * outs
|
||||
else:
|
||||
raise NotImplementedError("Non p2pkh transaction size estimation not" +
|
||||
"yet implemented")
|
||||
|
||||
def mktx(ins, outs):
|
||||
#Copy-paste from bitcoin-joinmarket
|
||||
txobj = {"locktime": 0, "version": 1, "ins": [], "outs": []}
|
||||
for i in ins:
|
||||
if isinstance(i, dict) and "outpoint" in i:
|
||||
txobj["ins"].append(i)
|
||||
else:
|
||||
if isinstance(i, dict) and "output" in i:
|
||||
i = i["output"]
|
||||
txobj["ins"].append({
|
||||
"outpoint": {"hash": i[:64],
|
||||
"index": int(i[65:])},
|
||||
"script": "",
|
||||
"sequence": 4294967295
|
||||
})
|
||||
for o in outs:
|
||||
if not isinstance(o, dict):
|
||||
addr = o[:o.find(':')]
|
||||
val = int(o[o.find(':') + 1:])
|
||||
o = {}
|
||||
if re.match('^[0-9a-fA-F]*$', addr):
|
||||
o["script"] = addr
|
||||
else:
|
||||
o["address"] = addr
|
||||
o["value"] = val
|
||||
|
||||
outobj = {}
|
||||
if "address" in o:
|
||||
outobj["script"] = address_to_script(o["address"])
|
||||
elif "script" in o:
|
||||
outobj["script"] = o["script"]
|
||||
else:
|
||||
raise Exception("Could not find 'address' or 'script' in output.")
|
||||
outobj["value"] = o["value"]
|
||||
txobj["outs"].append(outobj)
|
||||
|
||||
return serialize(txobj)
|
||||
|
||||
def set_commitment_file(file_location):
|
||||
global PODLE_COMMIT_FILE
|
||||
PODLE_COMMIT_FILE = file_location
|
||||
|
||||
def test_btc():
|
||||
#Sign and verify test (for message signing in joinmarket handshake)
|
||||
print("Using interface " + interface)
|
||||
priv = dbl_sha256("hello") + "01"
|
||||
x = ecdsa_sign("helloxxx", priv)
|
||||
log.debug("Got: " + x)
|
||||
y = ecdsa_verify("helloxxx", x, privkey_to_pubkey(priv))
|
||||
log.debug("Sig ver: " + str(y))
|
||||
assert y
|
||||
|
||||
#address/script conversion test
|
||||
test_addr = "1LT6rwv26bV7mgvRosoSCyGM7ttVRsYidP"
|
||||
#Electrum has no support for testnet!
|
||||
#test_test_addr = "mgvipZr8kX7fZFQU7QsKTCJT9QCfaiswV7"
|
||||
assert script_to_address(address_to_script(test_addr))==test_addr
|
||||
assert get_version_byte(test_addr)==0
|
||||
|
||||
#Transaction creation test.
|
||||
raw_valid_tx = "01000000064cdfe43ad43b187b738644363144784a09bf6d408012409cf9934591109a789b060000006b483045022100d4309edbb8253e62fb59462f2ff5c3445923e0299bf1a15ac5f7db3da5752bee022066f3f219de7e6ee56c3d600da757ec1051cbd11b42969b8935ae35642b6a2e84012102e94b49525342110266a1dc7651221507318c4cb914ede004b3098650e9b951b6ffffffffc2a9b3e8285c2e7aaee2ea50f792172c920c43a675fa8e8d70976727c8752adf030000006a47304402202763d8ad9e41c99c5af587c69d267493773dc9567519a64db8b707af5daf07f0022011729c6d241ad5abe48687d084644bd442b5f9038db04fb28da674126183aca5012102d2cbeb9386fd201bc6eecf27b2858f7bc27462cd9b43ae464e9ef3281f97a3e0ffffffffa787e89792a93111ff08f5a083234c7c2410bd69b6eef42be0fc5f026a3a1cf0030000006b483045022100c3b86d7acadf1be3d8ea6706daedb842b09732621e830440481370d423703741022009fd0f90a07babd481f1011ec883b2aa248c6a4a433599c5b203c6b93fc03b67012103f9a47d3958281b6749921fdf6d9edde0176342c00ced7caacab9ab3a64795086ffffffff23fb90cebcb1784a7a4a0a35489356ba64cf95c0afdc5a0f0184dc22668ff41f050000006b483045022100ea698e5952e23ffdf6d58bdc73e91c555867e3ad99ac9b583f492882395ace9a0220705abe597972d45923fe0515695dd7b99dcfa50e69d49c03a8126180fd263bc70121036532aa886851548a5b62bff29b4c36bfdc33e68c7dbee8efb4b440e50c5ebc6effffffffd401de8afd8fd323ab6abd9db1d261ac69e7c1d2be7f1a40004e7659b7d6cd9b030000006b483045022100b09c4e7f227f2f86d1965edbc4c92b9058243300f3bc62a3169591aacb60ca4d0220390d0d7ae2ee7dab200e166337c65d4a62b576dc4fa138ce40efd240c57346fc0121034cd59665d736d927d9613c7624f8d616d483b06ab8993446f6119f18e22731feffffffff38b8b3ae5fe9ef09c9f1583c9d6cc128bbd2639d49aca97b7686a74ba91bb32a040000006a4730440220105d93aba953edf008cc5b16ac81c10d97db6e59a3e13062ceef7cc1fbffd2ad022027b14b4162d70c4448bec7cb086b4e52880b51b282de98019ec3038153e25ed0012102cdbfb52b3e164203845f72391a3a58205834a3ad473a9d9878488dc1594aa0d4ffffffff087edb0000000000001976a914a1e5f40c6171e91183533f16bbda35e45182bcfa88ac80d97800000000001976a91482985ea6f877d70692072af967af305005fc86fd88ac80d97800000000001976a914a698b206b9f654974afd2056c85c52f88e4c2b2488ac9970af05000000001976a914b05dbb0ede1191e2871209affd8a5922e0a3275288ac80d97800000000001976a914619b3b22b7b66220d22907b8600724aecc49f03488acabc80000000000001976a914911c8c57eb12aa2c1cdce92f82c7e0405a2f3c6988ac80d97800000000001976a91464cd0ed04862f2b7101e9394285d2b3066e5e4dc88ac13b14100000000001976a9143f81fa4fd890845882fbb5226539d9643c99f0f488ac00000000"
|
||||
rvtxid = "4489a8cc933cb4e94915ead5b57b4aa707212c1f7b317187b500491e068c7887"
|
||||
if interface == "joinmarket-electrum":
|
||||
t = etr.Transaction(raw_valid_tx)
|
||||
assert rvtxid == t.hash()
|
||||
|
||||
#Transaction deserialization/serialization test
|
||||
#Electrum requires this call to fill out Transactionfields
|
||||
t.deserialize()
|
||||
#log.debug("Got inputs: " + str(t.inputs))
|
||||
ourdeser = deserialize(t.raw)
|
||||
ourraw = serialize(ourdeser)
|
||||
#log.debug("Recreated: \n" + ourraw)
|
||||
assert ourraw == raw_valid_tx
|
||||
#double check round trip too
|
||||
assert deserialize(ourraw) == ourdeser
|
||||
txinslist = t.inputs()
|
||||
elif interface == "joinmarket-joinmarket":
|
||||
assert serialize(deserialize(raw_valid_tx)) == raw_valid_tx
|
||||
t = deserialize(raw_valid_tx)
|
||||
txinslist = t["ins"]
|
||||
else:
|
||||
raise NotImplementedError("No such interface?")
|
||||
|
||||
#Transaction signature verification tests.
|
||||
#All currently assuming 100% p2pkh.
|
||||
for i, tin in enumerate(txinslist):
|
||||
if interface == "joinmarket-electrum":
|
||||
script = address_to_script(tin["address"])
|
||||
sig = tin["signatures"][0]
|
||||
pub = tin["pubkeys"][0]
|
||||
elif interface == "joinmarket-joinmarket":
|
||||
log.debug("Joinmarket working with this script: " + tin["script"])
|
||||
scriptSig = tin["script"]
|
||||
#We need to parse out the pubkey, convert to address, then convert
|
||||
#to a pubkeyscript; this assumes p2pkh. Note that this is handled
|
||||
#internally by the joinmarket blockchain/maker/taker code, so only
|
||||
#for tests.
|
||||
pub = scriptSig[-66:]
|
||||
script = address_to_script(pubkey_to_address(pub))
|
||||
log.debug("Converted to this addr script: " + script)
|
||||
#drop the length bytes from the start of sig and pub
|
||||
sig = scriptSig[2:-68]
|
||||
else:
|
||||
raise NotImplementedError("No such interface?")
|
||||
log.debug("Got sig, script, pub: " + " ".join([sig, script, pub]))
|
||||
assert verify_tx_input(raw_valid_tx, i, script, sig, pub)
|
||||
log.debug("Sig at: " + str(i) + " OK.")
|
||||
|
||||
#Note there are no transaction signing tests, as
|
||||
#this is done by the wallet in this interface.
|
||||
log.debug("All tests passed.")
|
||||
|
|
@ -17,10 +17,11 @@ import json
|
|||
import hashlib
|
||||
import os
|
||||
import sys
|
||||
from jmclient import (jm_single, get_irc_mchannels, get_log, get_p2sh_vbyte,
|
||||
from jmbase import get_log
|
||||
from jmclient import (jm_single, get_irc_mchannels, get_p2sh_vbyte,
|
||||
RegtestBitcoinCoreInterface)
|
||||
from .output import fmt_tx_data
|
||||
from . import btc
|
||||
import jmbitcoin as btc
|
||||
|
||||
jlog = get_log()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from __future__ import (absolute_import, division,
|
|||
from builtins import * # noqa: F401
|
||||
|
||||
import sys
|
||||
import jmclient.btc as btc
|
||||
import jmbitcoin as btc
|
||||
from jmclient import jm_single, get_p2pk_vbyte, get_p2sh_vbyte
|
||||
|
||||
def quit(parser, errmsg): #pragma: no cover
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import binascii
|
|||
|
||||
from configparser import ConfigParser, NoOptionError
|
||||
|
||||
from . import btc
|
||||
import jmbitcoin as btc
|
||||
from jmclient.jsonrpc import JsonRpc
|
||||
from jmbase.support import (get_log, joinmarket_alert, core_alert, debug_silence,
|
||||
set_logging_level)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ from binascii import hexlify, unhexlify
|
|||
from collections import OrderedDict
|
||||
import struct
|
||||
|
||||
|
||||
from . import btc
|
||||
import jmbitcoin as btc
|
||||
from .configure import get_network
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from __future__ import (absolute_import, division,
|
|||
print_function, unicode_literals)
|
||||
from builtins import * # noqa: F401
|
||||
from future.utils import iteritems
|
||||
from . import btc
|
||||
import jmbitcoin as btc
|
||||
import json
|
||||
import queue as Queue
|
||||
import os
|
||||
|
|
@ -18,7 +18,7 @@ from twisted.protocols.basic import LineReceiver
|
|||
from twisted.internet import reactor, task, defer
|
||||
from .blockchaininterface import BlockchainInterface
|
||||
from .configure import get_p2sh_vbyte
|
||||
from .support import get_log
|
||||
from jmbase import get_log
|
||||
from .electrum_data import get_default_servers, set_electrum_testnet,\
|
||||
DEFAULT_PROTO
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import base64
|
|||
import http.client
|
||||
import json
|
||||
from decimal import Decimal
|
||||
from jmclient import get_log
|
||||
from jmbase import get_log
|
||||
|
||||
jlog = get_log()
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ import sys
|
|||
import abc
|
||||
from binascii import unhexlify
|
||||
|
||||
from . import btc
|
||||
from .btc import SerializationError, SerializationTruncationError
|
||||
|
||||
from jmbitcoin import SerializationError, SerializationTruncationError
|
||||
import jmbitcoin as btc
|
||||
from jmclient.configure import jm_single
|
||||
from jmbase.support import get_log
|
||||
from jmclient.support import (calc_cj_fee)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import hashlib
|
|||
import json
|
||||
import binascii
|
||||
import struct
|
||||
from .btc import multiply, add_pubkeys, getG, podle_PublicKey,\
|
||||
from jmbitcoin import multiply, add_pubkeys, getG, podle_PublicKey,\
|
||||
podle_PrivateKey, encode, decode, N, podle_PublicKey_class
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import pprint
|
|||
import random
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
from . import btc
|
||||
import jmbitcoin as btc
|
||||
from jmclient.configure import get_p2sh_vbyte, jm_single, validate_address
|
||||
from jmbase.support import get_log
|
||||
from jmclient.support import (calc_cj_fee, weighted_order_choose, choose_orders,
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ import os
|
|||
import time
|
||||
import numbers
|
||||
from binascii import hexlify, unhexlify
|
||||
from .configure import get_log, jm_single, validate_address
|
||||
from jmbase import get_log
|
||||
from .configure import jm_single, validate_address
|
||||
from .schedule import human_readable_schedule_entry, tweak_tumble_schedule,\
|
||||
schedule_to_text
|
||||
from .wallet import BaseWallet, estimate_tx_fee
|
||||
from .btc import deserialize, mktx, serialize, txhash
|
||||
from jmbitcoin import deserialize, mktx, serialize, txhash
|
||||
log = get_log()
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ from .support import select_gradual, select_greedy, select_greediest, \
|
|||
from .cryptoengine import BTC_P2PKH, BTC_P2SH_P2WPKH, TYPE_P2PKH, \
|
||||
TYPE_P2SH_P2WPKH
|
||||
from .support import get_random_bytes
|
||||
from . import mn_encode, mn_decode, btc
|
||||
from . import mn_encode, mn_decode
|
||||
import jmbitcoin as btc
|
||||
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from jmclient import (get_network, WALLET_IMPLEMENTATIONS, Storage, podle,
|
|||
is_segwit_mode, SegwitLegacyWallet, LegacyWallet)
|
||||
from jmbase.support import get_password
|
||||
from .cryptoengine import TYPE_P2PKH, TYPE_P2SH_P2WPKH
|
||||
import jmclient.btc as btc
|
||||
import jmbitcoin as btc
|
||||
|
||||
|
||||
# used for creating new wallets
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ import time
|
|||
import abc
|
||||
from twisted.python.log import startLogging
|
||||
from optparse import OptionParser
|
||||
from jmclient import Maker, jm_single, load_program_config, get_log,\
|
||||
from jmbase import get_log
|
||||
from jmclient import Maker, jm_single, load_program_config, \
|
||||
sync_wallet, JMClientProtocolFactory, start_reactor, calc_cj_fee
|
||||
from .wallet_utils import open_test_wallet_maybe, get_wallet_path
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ import binascii
|
|||
import random
|
||||
from decimal import Decimal
|
||||
|
||||
from jmbase import get_log
|
||||
from jmclient import (
|
||||
jm_single, open_test_wallet_maybe, get_log, estimate_tx_fee,
|
||||
jm_single, open_test_wallet_maybe, estimate_tx_fee,
|
||||
BlockchainInterface, get_p2sh_vbyte, BIP32Wallet, SegwitLegacyWallet)
|
||||
from jmbase.support import chunks
|
||||
import jmbitcoin as btc
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ import binascii
|
|||
from commontest import create_wallet_for_sync
|
||||
|
||||
import pytest
|
||||
from jmclient import load_program_config, jm_single, sync_wallet, get_log
|
||||
from jmbase import get_log
|
||||
from jmclient import load_program_config, jm_single, sync_wallet
|
||||
|
||||
log = get_log()
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ from __future__ import (absolute_import, division,
|
|||
from builtins import *
|
||||
'''test client-protocol interfacae.'''
|
||||
|
||||
from jmclient import load_program_config, Taker, get_log,\
|
||||
from jmbase import get_log
|
||||
from jmclient import load_program_config, Taker,\
|
||||
JMClientProtocolFactory, jm_single, Maker
|
||||
from jmclient.client_protocol import JMTakerClientProtocol
|
||||
from twisted.python.log import msg as tmsg
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ import sys
|
|||
import pytest
|
||||
from twisted.internet import reactor
|
||||
|
||||
from jmclient import load_program_config, jm_single, get_log,\
|
||||
from jmbase import get_log
|
||||
from jmclient import load_program_config, jm_single, \
|
||||
YieldGeneratorBasic, Taker, sync_wallet, LegacyWallet, SegwitLegacyWallet
|
||||
from jmclient.podle import set_commitment_file
|
||||
from commontest import make_wallets, binarize_tx
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ from __future__ import (absolute_import, division,
|
|||
print_function, unicode_literals)
|
||||
from builtins import * # noqa: F401
|
||||
|
||||
from jmclient import Maker, btc, get_p2sh_vbyte, get_p2pk_vbyte, \
|
||||
import jmbitcoin as btc
|
||||
from jmclient import Maker, get_p2sh_vbyte, get_p2pk_vbyte, \
|
||||
load_program_config, jm_single
|
||||
import jmclient
|
||||
from commontest import DummyBlockchainInterface
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ import struct
|
|||
import json
|
||||
import pytest
|
||||
import copy
|
||||
from jmclient import load_program_config, get_log, jm_single, generate_podle,\
|
||||
from jmbase import get_log
|
||||
from jmclient import load_program_config, jm_single, generate_podle,\
|
||||
generate_podle_error_string, get_commitment_file, PoDLE,\
|
||||
get_podle_commitments, add_external_commitments, update_commitments
|
||||
from jmclient.podle import verify_all_NUMS, verify_podle, PoDLEError
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ from commontest import make_wallets, make_sign_and_push
|
|||
|
||||
import jmbitcoin as bitcoin
|
||||
import pytest
|
||||
from jmbase import get_log
|
||||
from jmclient import load_program_config, jm_single, sync_wallet,\
|
||||
get_p2pk_vbyte, get_log
|
||||
get_p2pk_vbyte
|
||||
|
||||
log = get_log()
|
||||
#just a random selection of pubkeys for receiving multisigs;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ from binascii import hexlify, unhexlify
|
|||
import pytest
|
||||
import jmbitcoin as btc
|
||||
from commontest import binarize_tx
|
||||
from jmclient import load_program_config, jm_single, get_log,\
|
||||
from jmbase import get_log
|
||||
from jmclient import load_program_config, jm_single, \
|
||||
SegwitLegacyWallet,BIP32Wallet, BIP49Wallet, LegacyWallet,\
|
||||
VolatileStorage, get_network, cryptoengine, WalletError
|
||||
from test_blockchaininterface import sync_test_wallet
|
||||
|
|
|
|||
|
|
@ -11,8 +11,9 @@ from commontest import create_wallet_for_sync, make_sign_and_push
|
|||
import json
|
||||
|
||||
import pytest
|
||||
from jmbase import get_log
|
||||
from jmclient import (
|
||||
load_program_config, jm_single, sync_wallet, get_log,
|
||||
load_program_config, jm_single, sync_wallet,
|
||||
estimate_tx_fee, BitcoinCoreInterface, Mnemonic)
|
||||
from taker_test_data import t_raw_signed_tx
|
||||
testdir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import time
|
|||
|
||||
from jmdaemon.message_channel import MessageChannel
|
||||
from jmdaemon.protocol import *
|
||||
from jmclient import get_log
|
||||
from jmbase import get_log
|
||||
from msgdata import *
|
||||
|
||||
log = get_log()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ from jmdaemon.orderbookwatch import OrderbookWatch
|
|||
from jmdaemon.daemon_protocol import JMDaemonServerProtocol
|
||||
from jmdaemon.protocol import NICK_HASH_LENGTH, NICK_MAX_ENCODED, JM_VERSION,\
|
||||
JOINMARKET_NICK_HEADER
|
||||
from jmclient import (load_program_config, get_log, jm_single, get_irc_mchannels)
|
||||
from jmbase import get_log
|
||||
from jmclient import (load_program_config, jm_single, get_irc_mchannels)
|
||||
from twisted.python.log import msg as tmsg
|
||||
from twisted.python.log import startLogging
|
||||
from twisted.internet import protocol, reactor, task
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from jmdaemon.message_channel import MChannelThread
|
|||
from jmdaemon.orderbookwatch import OrderbookWatch
|
||||
from jmdaemon.protocol import COMMAND_PREFIX, NICK_HASH_LENGTH,\
|
||||
NICK_MAX_ENCODED, JM_VERSION, JOINMARKET_NICK_HEADER
|
||||
from jmclient import get_log
|
||||
from jmbase import get_log
|
||||
from msgdata import *
|
||||
import time
|
||||
import hashlib
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import binascii
|
|||
from pprint import pformat
|
||||
|
||||
from optparse import OptionParser
|
||||
import jmclient.btc as btc
|
||||
import jmbitcoin as btc
|
||||
from jmclient import load_program_config, jm_single, get_p2pk_vbyte,\
|
||||
open_wallet, sync_wallet, add_external_commitments, update_commitments,\
|
||||
PoDLE, get_podle_commitments, get_utxo_info, validate_utxo_data, quit,\
|
||||
|
|
|
|||
|
|
@ -64,9 +64,10 @@ JM_CORE_VERSION = '0.5.0'
|
|||
#Version of this Qt script specifically
|
||||
JM_GUI_VERSION = '8'
|
||||
|
||||
from jmbase import get_log
|
||||
from jmclient import load_program_config, get_network,\
|
||||
open_test_wallet_maybe, get_wallet_path, get_p2sh_vbyte, get_p2pk_vbyte,\
|
||||
jm_single, validate_address, get_log, weighted_order_choose, Taker,\
|
||||
jm_single, validate_address, weighted_order_choose, Taker,\
|
||||
JMClientProtocolFactory, start_reactor, get_schedule, schedule_to_text,\
|
||||
get_blockchain_interface_instance, direct_send,\
|
||||
RegtestBitcoinCoreInterface, tumbler_taker_finished_update,\
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ except:
|
|||
"in the joinmarket virtualenv.")
|
||||
sys.exit(0)
|
||||
|
||||
from jmclient import jm_single, load_program_config, get_log, calc_cj_fee, get_irc_mchannels
|
||||
from jmbase import get_log
|
||||
from jmclient import jm_single, load_program_config, calc_cj_fee, get_irc_mchannels
|
||||
from jmdaemon import OrderbookWatch, MessageChannelCollection, IRCMessageChannel
|
||||
#TODO this is only for base58, find a solution for a client without jmbitcoin
|
||||
import jmbitcoin as btc
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@ for other reasons).
|
|||
|
||||
from pprint import pformat
|
||||
from optparse import OptionParser
|
||||
import jmclient.btc as btc
|
||||
import jmbitcoin as btc
|
||||
from jmbase import get_log
|
||||
from jmclient import load_program_config, estimate_tx_fee, jm_single,\
|
||||
get_p2pk_vbyte, validate_address, get_log, get_utxo_info,\
|
||||
get_p2pk_vbyte, validate_address, get_utxo_info,\
|
||||
validate_utxo_data, quit
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ from future.utils import iteritems
|
|||
|
||||
import random
|
||||
|
||||
from jmclient import YieldGeneratorBasic, ygmain, get_log, jm_single
|
||||
from jmbase import get_log
|
||||
from jmclient import YieldGeneratorBasic, ygmain, jm_single
|
||||
|
||||
|
||||
# This is a maker for the purposes of generating a yield from held bitcoins
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ from __future__ import (absolute_import, division,
|
|||
print_function, unicode_literals)
|
||||
from builtins import * # noqa: F401
|
||||
|
||||
|
||||
from jmclient import YieldGeneratorBasic, ygmain, get_log
|
||||
from jmbase import get_log
|
||||
from jmclient import YieldGeneratorBasic, ygmain
|
||||
|
||||
"""THESE SETTINGS CAN SIMPLY BE EDITED BY HAND IN THIS FILE:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ from decimal import Decimal
|
|||
data_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||
sys.path.insert(0, os.path.join(data_dir))
|
||||
|
||||
from jmbase import get_log
|
||||
from jmclient import open_test_wallet_maybe, BIP32Wallet, SegwitLegacyWallet, \
|
||||
get_log, estimate_tx_fee, jm_single
|
||||
estimate_tx_fee, jm_single
|
||||
import jmbitcoin as btc
|
||||
from jmbase import chunks
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ from common import make_wallets
|
|||
from pprint import pformat
|
||||
import jmbitcoin as btc
|
||||
import pytest
|
||||
from jmclient import load_program_config, jm_single, get_log, LegacyWallet
|
||||
from jmbase import get_log
|
||||
from jmclient import load_program_config, jm_single, LegacyWallet
|
||||
log = get_log()
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue