Browse Source

update Taker code to use segwit wallet

master
Adam Gibson 9 years ago
parent
commit
94d7b45399
No known key found for this signature in database
GPG Key ID: B3AE09F1E9A3197A
  1. 23
      jmclient/jmclient/blockchaininterface.py
  2. 1
      jmclient/jmclient/configure.py
  3. 8
      jmclient/jmclient/support.py
  4. 39
      jmclient/jmclient/taker.py
  5. 2
      jmdaemon/jmdaemon/orderbookwatch.py
  6. 4
      jmdaemon/jmdaemon/protocol.py
  7. 4
      scripts/joinmarket-qt.py

23
jmclient/jmclient/blockchaininterface.py

@ -68,7 +68,8 @@ class BlockchainInterface(object):
unconfirmfun, unconfirmfun,
confirmfun, confirmfun,
notifyaddr, notifyaddr,
timeoutfun=None): timeoutfun=None,
vb=None):
""" """
Invokes unconfirmfun and confirmfun when tx is seen on the network Invokes unconfirmfun and confirmfun when tx is seen on the network
If timeoutfun not None, called with boolean argument that tells If timeoutfun not None, called with boolean argument that tells
@ -242,7 +243,9 @@ class BlockchaininfoInterface(BlockchainInterface):
log.info('blockchaininfo sync_unspent took ' + log.info('blockchaininfo sync_unspent took ' +
str((self.last_sync_unspent - st)) + 'sec') str((self.last_sync_unspent - st)) + 'sec')
def add_tx_notify(self, txd, unconfirmfun, confirmfun, notifyaddr): def add_tx_notify(self, txd, unconfirmfun, confirmfun, notifyaddr, vb=None):
if not vb:
vb = get_p2pk_vbyte()
unconfirm_timeout = 10 * 60 # seconds unconfirm_timeout = 10 * 60 # seconds
unconfirm_poll_period = 15 unconfirm_poll_period = 15
confirm_timeout = 2 * 60 * 60 confirm_timeout = 2 * 60 * 60
@ -258,7 +261,7 @@ class BlockchaininfoInterface(BlockchainInterface):
self.tx_output_set = set([(sv['script'], sv['value']) self.tx_output_set = set([(sv['script'], sv['value'])
for sv in txd['outs']]) for sv in txd['outs']])
self.output_addresses = [ self.output_addresses = [
btc.script_to_address(scrval[0], get_p2pk_vbyte()) btc.script_to_address(scrval[0], vb)
for scrval in self.tx_output_set] for scrval in self.tx_output_set]
log.debug('txoutset=' + pprint.pformat(self.tx_output_set)) log.debug('txoutset=' + pprint.pformat(self.tx_output_set))
log.debug('outaddrs=' + ','.join(self.output_addresses)) log.debug('outaddrs=' + ','.join(self.output_addresses))
@ -615,7 +618,10 @@ class BlockrInterface(BlockchainInterface): #pragma: no cover
unconfirmfun, unconfirmfun,
confirmfun, confirmfun,
notifyaddr, notifyaddr,
timeoutfun=None): timeoutfun=None,
vb=None):
if not vb:
vb = get_p2pk_vbyte()
unconfirm_timeout = jm_single().config.getint('TIMEOUT', unconfirm_timeout = jm_single().config.getint('TIMEOUT',
'unconfirm_timeout_sec') 'unconfirm_timeout_sec')
unconfirm_poll_period = 5 unconfirm_poll_period = 5
@ -636,7 +642,7 @@ class BlockrInterface(BlockchainInterface): #pragma: no cover
self.tx_output_set = set([(sv['script'], sv['value']) self.tx_output_set = set([(sv['script'], sv['value'])
for sv in txd['outs']]) for sv in txd['outs']])
self.output_addresses = [ self.output_addresses = [
btc.script_to_address(scrval[0], get_p2pk_vbyte()) btc.script_to_address(scrval[0], vb)
for scrval in self.tx_output_set for scrval in self.tx_output_set
] ]
log.debug('txoutset=' + pprint.pformat(self.tx_output_set)) log.debug('txoutset=' + pprint.pformat(self.tx_output_set))
@ -1222,13 +1228,16 @@ class BitcoinCoreInterface(BlockchainInterface):
unconfirmfun, unconfirmfun,
confirmfun, confirmfun,
notifyaddr, notifyaddr,
timeoutfun=None): timeoutfun=None,
vb=None):
if not vb:
vb = get_p2pk_vbyte()
if not self.notifythread: if not self.notifythread:
self.notifythread = BitcoinCoreNotifyThread(self) self.notifythread = BitcoinCoreNotifyThread(self)
self.notifythread.start() self.notifythread.start()
one_addr_imported = False one_addr_imported = False
for outs in txd['outs']: for outs in txd['outs']:
addr = btc.script_to_address(outs['script'], get_p2pk_vbyte()) addr = btc.script_to_address(outs['script'], vb)
if self.rpc('getaccount', [addr]) != '': if self.rpc('getaccount', [addr]) != '':
one_addr_imported = True one_addr_imported = True
break break

1
jmclient/jmclient/configure.py

@ -66,7 +66,6 @@ global_singleton.DUST_THRESHOLD = 10 * global_singleton.BITCOIN_DUST_THRESHOLD
global_singleton.bc_interface = None global_singleton.bc_interface = None
global_singleton.maker_timeout_sec = 60 global_singleton.maker_timeout_sec = 60
global_singleton.debug_file_lock = threading.Lock() global_singleton.debug_file_lock = threading.Lock()
global_singleton.ordername_list = ["reloffer", "absoffer"]
global_singleton.debug_file_handle = None global_singleton.debug_file_handle = None
global_singleton.blacklist_file_lock = threading.Lock() global_singleton.blacklist_file_lock = threading.Lock()
global_singleton.core_alert = core_alert global_singleton.core_alert = core_alert

8
jmclient/jmclient/support.py

@ -157,9 +157,9 @@ def select_greediest(unspent, value):
def calc_cj_fee(ordertype, cjfee, cj_amount): def calc_cj_fee(ordertype, cjfee, cj_amount):
if ordertype == 'absoffer': if ordertype in ['swabsoffer', 'absoffer']:
real_cjfee = int(cjfee) real_cjfee = int(cjfee)
elif ordertype == 'reloffer': elif ordertype in ['swreloffer', 'reloffer']:
real_cjfee = int((Decimal(cjfee) * Decimal(cj_amount)).quantize(Decimal( real_cjfee = int((Decimal(cjfee) * Decimal(cj_amount)).quantize(Decimal(
1))) 1)))
else: else:
@ -282,9 +282,9 @@ def choose_sweep_orders(offers,
sumtxfee_contribution = 0 sumtxfee_contribution = 0
for order in ordercombo: for order in ordercombo:
sumtxfee_contribution += order['txfee'] sumtxfee_contribution += order['txfee']
if order['ordertype'] == 'absoffer': if order['ordertype'] in ['swabsoffer', 'absoffer']:
sumabsfee += int(order['cjfee']) sumabsfee += int(order['cjfee'])
elif order['ordertype'] == 'reloffer': elif order['ordertype'] in ['swreloffer', 'reloffer']:
sumrelfee += Decimal(order['cjfee']) sumrelfee += Decimal(order['cjfee'])
#this is unreachable since calc_cj_fee must already have been called #this is unreachable since calc_cj_fee must already have been called
else: #pragma: no cover else: #pragma: no cover

39
jmclient/jmclient/taker.py

@ -9,7 +9,7 @@ import time
import copy import copy
import btc import btc
from jmclient.configure import jm_single, get_p2pk_vbyte, donation_address from jmclient.configure import jm_single, get_p2pk_vbyte, get_p2sh_vbyte
from jmbase.support import get_log from jmbase.support import get_log
from jmclient.support import (calc_cj_fee, weighted_order_choose, choose_orders, from jmclient.support import (calc_cj_fee, weighted_order_choose, choose_orders,
choose_sweep_orders) choose_sweep_orders)
@ -237,7 +237,8 @@ class Taker(object):
jlog.debug("Estimated ins: "+str(est_ins)) jlog.debug("Estimated ins: "+str(est_ins))
est_outs = 2*self.n_counterparties + 1 est_outs = 2*self.n_counterparties + 1
jlog.debug("Estimated outs: "+str(est_outs)) jlog.debug("Estimated outs: "+str(est_outs))
estimated_fee = estimate_tx_fee(est_ins, est_outs) estimated_fee = estimate_tx_fee(est_ins, est_outs,
txtype=self.wallet.get_txtype())
jlog.info("We have a fee estimate: "+str(estimated_fee)) jlog.info("We have a fee estimate: "+str(estimated_fee))
jlog.info("And a requested fee of: "+str( jlog.info("And a requested fee of: "+str(
self.txfee_default * self.n_counterparties)) self.txfee_default * self.n_counterparties))
@ -451,11 +452,31 @@ class Taker(object):
for i, u in utxo.iteritems(): for i, u in utxo.iteritems():
if utxo_data[i] is None: if utxo_data[i] is None:
continue continue
#Check if the sender serialize_scripted the witness
#item into the sig message; if so, also pick up the amount
#from the utxo data retrieved from the blockchain to verify
#the segwit-style signature. Note that this allows a mixed
#SW/non-SW transaction as each utxo is interpreted separately.
sig_deserialized = btc.deserialize_script(sig)
if len(sig_deserialized) == 2:
ver_sig, ver_pub = sig_deserialized
wit = None
elif len(sig_deserialized) == 3:
ver_sig, ver_pub, wit = sig_deserialized
else:
jlog.debug("Invalid signature message - more than 3 items")
break
ver_amt = utxo_data[i]['value'] if wit else None
sig_good = btc.verify_tx_input(txhex, u[0], utxo_data[i]['script'], sig_good = btc.verify_tx_input(txhex, u[0], utxo_data[i]['script'],
*btc.deserialize_script(sig)) ver_sig, ver_pub, witness=wit,
amount=ver_amt)
if sig_good: if sig_good:
jlog.debug('found good sig at index=%d' % (u[0])) jlog.debug('found good sig at index=%d' % (u[0]))
self.latest_tx['ins'][u[0]]['script'] = sig if wit:
self.latest_tx["ins"][u[0]]["txinwitness"] = [ver_sig, ver_pub]
self.latest_tx["ins"][u[0]]["script"] = "16" + wit
else:
self.latest_tx["ins"][u[0]]["script"] = sig
inserted_sig = True inserted_sig = True
# check if maker has sent everything possible # check if maker has sent everything possible
self.utxos[nick].remove(u[1]) self.utxos[nick].remove(u[1])
@ -593,9 +614,9 @@ class Taker(object):
#Note: donation code removed (possibly temporarily) #Note: donation code removed (possibly temporarily)
raise NotImplementedError raise NotImplementedError
def sign_tx(self, tx, i, priv): def sign_tx(self, tx, i, priv, amount):
if self.my_cj_addr: if self.my_cj_addr:
return btc.sign(tx, i, priv) return self.wallet.sign(tx, i, priv, amount)
else: else:
#Note: donation code removed (possibly temporarily) #Note: donation code removed (possibly temporarily)
raise NotImplementedError raise NotImplementedError
@ -620,7 +641,9 @@ class Taker(object):
if utxo not in self.input_utxos.keys(): if utxo not in self.input_utxos.keys():
continue continue
addr = self.input_utxos[utxo]['address'] addr = self.input_utxos[utxo]['address']
tx = self.sign_tx(tx, index, self.wallet.get_key_from_addr(addr)) amount = self.input_utxos[utxo]["value"]
tx = self.sign_tx(tx, index, self.wallet.get_key_from_addr(addr),
amount)
self.latest_tx = btc.deserialize(tx) self.latest_tx = btc.deserialize(tx)
def push(self): def push(self):
@ -652,7 +675,7 @@ class Taker(object):
else: else:
jm_single().bc_interface.add_tx_notify( jm_single().bc_interface.add_tx_notify(
self.latest_tx, self.unconfirm_callback, self.latest_tx, self.unconfirm_callback,
self.confirm_callback, self.my_cj_addr) self.confirm_callback, self.my_cj_addr, vb=get_p2sh_vbyte())
if nick_to_use: if nick_to_use:
return (nick_to_use, tx) return (nick_to_use, tx)
#if push was not successful, return None #if push was not successful, return None

2
jmdaemon/jmdaemon/orderbookwatch.py

@ -95,7 +95,7 @@ class OrderbookWatch(object):
"from {}").format "from {}").format
log.debug(fmt(minsize, maxsize, counterparty)) log.debug(fmt(minsize, maxsize, counterparty))
return return
if ordertype == 'absoffer' and not isinstance(cjfee, int): if ordertype in ['swabsoffer', 'absoffer'] and not isinstance(cjfee, int):
try: try:
cjfee = int(cjfee) cjfee = int(cjfee)
except ValueError: except ValueError:

4
jmdaemon/jmdaemon/protocol.py

@ -8,6 +8,10 @@ separator = " "
offertypes = {"reloffer": [(int, "oid"), (int, "minsize"), (int, "maxsize"), offertypes = {"reloffer": [(int, "oid"), (int, "minsize"), (int, "maxsize"),
(int, "txfee"), (float, "cjfee")], (int, "txfee"), (float, "cjfee")],
"absoffer": [(int, "oid"), (int, "minsize"), (int, "maxsize"), "absoffer": [(int, "oid"), (int, "minsize"), (int, "maxsize"),
(int, "txfee"), (int, "cjfee")],
"swreloffer": [(int, "oid"), (int, "minsize"), (int, "maxsize"),
(int, "txfee"), (float, "cjfee")],
"swabsoffer": [(int, "oid"), (int, "minsize"), (int, "maxsize"),
(int, "txfee"), (int, "cjfee")]} (int, "txfee"), (int, "cjfee")]}
offername_list = offertypes.keys() offername_list = offertypes.keys()

4
scripts/joinmarket-qt.py

@ -790,10 +790,10 @@ class SpendTab(QWidget):
mbinfo.append("Counterparties chosen:") mbinfo.append("Counterparties chosen:")
mbinfo.append('Name, Order id, Coinjoin fee (sat.)') mbinfo.append('Name, Order id, Coinjoin fee (sat.)')
for k, o in offers.iteritems(): for k, o in offers.iteritems():
if o['ordertype'] == 'reloffer': if o['ordertype'] in ['swreloffer', 'reloffer']:
display_fee = int(self.taker.cjamount * display_fee = int(self.taker.cjamount *
float(o['cjfee'])) - int(o['txfee']) float(o['cjfee'])) - int(o['txfee'])
elif o['ordertype'] == 'absoffer': elif o['ordertype'] in ['swabsoffer', 'absoffer']:
display_fee = int(o['cjfee']) - int(o['txfee']) display_fee = int(o['cjfee']) - int(o['txfee'])
else: else:
log.debug("Unsupported order type: " + str(o['ordertype']) + log.debug("Unsupported order type: " + str(o['ordertype']) +

Loading…
Cancel
Save