Skip to content

Commit

Permalink
TxHistory tab in Qt records coinjoins
Browse files Browse the repository at this point in the history
while in maker mode, and deposits (although
there is no sophisticated tx type parsing).
The location of the corresponding history
file is fixed to the datadir correctly.
Also fixed Maker start/stop for non-Tor case.
  • Loading branch information
AdamISZ committed Jan 10, 2020
1 parent 52bf7f0 commit 0fad076
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 20 deletions.
1 change: 1 addition & 0 deletions jmclient/jmclient/yieldgenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
import time
import abc
import sys
from twisted.python.log import startLogging
from optparse import OptionParser
from jmbase import get_log
Expand Down
1 change: 0 additions & 1 deletion jmdaemon/jmdaemon/daemon_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ def on_JM_MSGSIGNATURE_VERIFY(self, verif_result, nick, fullmsg, hostid):

@JMShutdown.responder
def on_JM_SHUTDOWN(self):
print("reached on shutdown in jmdaemonserverprotocol")
self.mc_shutdown()
self.jm_state = 0
return {'accepted': True}
Expand Down
11 changes: 8 additions & 3 deletions jmdaemon/jmdaemon/irc.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ def __init__(self,
self.tx_irc_client = None
#TODO can be configuration var, how long between reconnect attempts:
self.reconnect_interval = 10

# service is used to wrap endpoint for Tor connections:
self.reconnecting_service = None

#implementation of abstract base class methods;
#these are mostly but not exclusively acting as pass through
#to the wrapped twisted IRC client protocol
Expand All @@ -114,7 +118,8 @@ def run(self):
def shutdown(self):
self.tx_irc_client.quit()
self.give_up = True
self.myRS.stopService()
if self.reconnecting_service:
self.reconnecting_service.stopService()

def _pubmsg(self, msg):
self.tx_irc_client._pubmsg(msg)
Expand Down Expand Up @@ -157,8 +162,8 @@ def build_irc(self):
use_tls = False
ircEndpoint = TorSocksEndpoint(torEndpoint, self.serverport[0],
self.serverport[1], tls=use_tls)
self.myRS = ClientService(ircEndpoint, factory)
self.myRS.startService()
self.reconnecting_service = ClientService(ircEndpoint, factory)
self.reconnecting_service.startService()
else:
try:
factory = TxIRCFactory(self)
Expand Down
69 changes: 53 additions & 16 deletions scripts/joinmarket-qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import sys, datetime, os, logging
import platform, json, threading, time

import qrcode
from optparse import OptionParser

Expand Down Expand Up @@ -94,8 +95,9 @@ def update_config_for_gui():
'''
gui_config_names = ['gaplimit', 'history_file', 'check_high_fee',
'max_mix_depth', 'order_wait_time', 'checktx']
gui_config_default_vals = ['6', 'jm-tx-history.txt', '2', '5', '30',
'true']
gui_config_default_vals = ['6', os.path.join(jm_single().datadir,
'jm-tx-history.txt'),
'2', '5', '30', 'true']
if "GUI" not in jm_single().config.sections():
jm_single().config.add_section("GUI")
gui_items = jm_single().config.items("GUI")
Expand Down Expand Up @@ -638,7 +640,8 @@ def qt_directsend_callback(rtxd, rtxid, confs):
mainWindow.wallet_service.active_txids.append(txid)
mainWindow.wallet_service.register_callbacks([qt_directsend_callback],
txid, cb_type="confirmed")
self.persistTxToHistory(destaddr, self.direct_send_amount, txid)
mainWindow.centralWidget().widget(3).persistTxToHistory(destaddr,
self.direct_send_amount, txid)
self.cleanUp()
return

Expand Down Expand Up @@ -826,8 +829,8 @@ def takerFinished(self, res, fromtx=False, waittime=0.0, txdetails=None):
title="Success")
#TODO: theoretically possible to miss this if confirmed event
#seen before unconfirmed.
self.persistTxToHistory(self.taker.my_cj_addr, self.taker.cjamount,
self.taker.txid)
mainWindow.centralWidget().widget(3).persistTxToHistory(
self.taker.my_cj_addr, self.taker.cjamount, self.taker.txid)

#TODO prob best to completely fold multiple and tumble to reduce
#complexity/duplication
Expand Down Expand Up @@ -866,17 +869,6 @@ def takerFinished(self, res, fromtx=False, waittime=0.0, txdetails=None):
else:
self.giveUp()

def persistTxToHistory(self, addr, amt, txid):
#persist the transaction to history
with open(jm_single().config.get("GUI", "history_file"), 'ab') as f:
f.write((','.join([addr, btc.amount_to_btc_str(amt), txid,
datetime.datetime.now(
).strftime("%Y/%m/%d %H:%M:%S")])).encode('utf-8'))
f.write(b'\n') #TODO: Windows
#update the TxHistory tab
txhist = mainWindow.centralWidget().widget(3)
txhist.updateTxInfo()

def toggleButtons(self):
"""Refreshes accessibility of buttons in the (single, multiple) join
tabs based on the current state as defined by the SpendStateMgr instance.
Expand Down Expand Up @@ -956,6 +948,7 @@ class TxHistoryTab(QWidget):

def __init__(self):
super(TxHistoryTab, self).__init__()
self.txids = set()
self.initUI()

def initUI(self):
Expand All @@ -976,6 +969,19 @@ def getHeaders(self):
'''Function included in case dynamic in future'''
return ['Receiving address', 'Amount in BTC', 'Transaction id', 'Date']

def persistTxToHistory(self, addr, amt, txid):
#persist the transaction to history
if txid in self.txids:
# don't repeat entries
return
self.txids.add(txid)
with open(jm_single().config.get("GUI", "history_file"), 'ab') as f:
f.write((','.join([addr, btc.amount_to_btc_str(amt), txid,
datetime.datetime.now(
).strftime("%Y/%m/%d %H:%M:%S")])).encode('utf-8'))
f.write(b'\n') #TODO: Windows
self.updateTxInfo()

def updateTxInfo(self, txinfo=None):
self.tHTW.clear()
if not txinfo:
Expand All @@ -997,6 +1003,7 @@ def getTxInfoFromFile(self):
txlines = f.readlines()
for tl in txlines:
txhist.append(tl.decode('utf-8').strip().split(','))
self.txids.add(txhist[-1][2])
if not len(txhist[-1]) == 4:
JMQtMessageBox(self,
"Incorrectedly formatted file " + hf,
Expand Down Expand Up @@ -1687,6 +1694,7 @@ def loadWalletFromBlockchain(self, firstarg=None, pwd=None):
# add information callbacks:
self.wallet_service.add_restart_callback(self.restartWithMsg)
self.wallet_service.autofreeze_warning_cb = self.autofreeze_warning_cb
self.wallet_service.register_callbacks([self.updateTxHistory], None, cb_type="all")

self.wallet_service.startService()
self.walletRefresh = task.LoopingCall(self.updateWalletInfo)
Expand All @@ -1708,6 +1716,35 @@ def updateWalletInfo(self):
self.syncmsg = newsyncmsg
self.statusBar().showMessage(self.syncmsg)

def updateTxHistory(self, txd, txid):
""" If a transaction is seen by the wallet service
while running in maker mode, we update the tx history to
record the txid. We note *a* receiving address and the
corresponding amount; this is because a full analysis
requires detailed algos to account for custom deposit
patterns as well as coinjoin pattern analysis.
Note this is separate from the yigen log.
TODO implement these algos in WalletService.
TODO consolidate the multiple tx history functions.
"""

if not self.maker_running:
# these transactions are recorded separately
# (note that this includes direct sends)
return
addr_val = [None, None]
for o in txd["outs"]:
bscript = btc.safe_from_hex(o["script"])
if self.wallet_service.is_known_script(bscript):
addr_val = [self.wallet_service.script_to_addr(bscript),
o["value"]]
break
if addr_val[0] is None:
# it's possible to get notified of a transaction
# on this label that isn't in our wallet; ignore.
return
self.centralWidget().widget(3).persistTxToHistory(*addr_val, txid)

def generateWallet(self):
log.debug('generating wallet')
if jm_single().config.get("BLOCKCHAIN", "blockchain_source") == "regtest":
Expand Down

0 comments on commit 0fad076

Please sign in to comment.