Browse Source

use callFromThread for bci callbacks

master
Adam Gibson 9 years ago
parent
commit
7c5d8a1e1f
No known key found for this signature in database
GPG Key ID: B3AE09F1E9A3197A
  1. 9
      jmclient/jmclient/blockchaininterface.py
  2. 66
      jmclient/test/test_tx_notify.py

9
jmclient/jmclient/blockchaininterface.py

@ -15,6 +15,7 @@ import urllib
import urllib2 import urllib2
import traceback import traceback
from decimal import Decimal from decimal import Decimal
from twisted.internet import reactor
import btc import btc
@ -484,7 +485,7 @@ def bitcoincore_timeout_callback(uc_called, txout_set, txnotify_fun_list,
return return
txnotify_fun_list.remove(txnotify_tuple) txnotify_fun_list.remove(txnotify_tuple)
log.debug('timeoutfun txout_set=\n' + pprint.pformat(txout_set)) log.debug('timeoutfun txout_set=\n' + pprint.pformat(txout_set))
timeoutfun(uc_called) reactor.callFromThread(timeoutfun, uc_called)
class NotifyRequestHeader(BaseHTTPServer.BaseHTTPRequestHandler): class NotifyRequestHeader(BaseHTTPServer.BaseHTTPRequestHandler):
@ -538,7 +539,7 @@ class NotifyRequestHeader(BaseHTTPServer.BaseHTTPRequestHandler):
break break
assert txdata is not None assert txdata is not None
if txdata['confirmations'] == 0: if txdata['confirmations'] == 0:
unconfirmfun(txd, txid) reactor.callFromThread(unconfirmfun, txd, txid)
# TODO pass the total transfered amount value here somehow # TODO pass the total transfered amount value here somehow
# wallet_name = self.get_wallet_name() # wallet_name = self.get_wallet_name()
# amount = # amount =
@ -556,10 +557,10 @@ class NotifyRequestHeader(BaseHTTPServer.BaseHTTPRequestHandler):
timeoutfun)).start() timeoutfun)).start()
else: else:
if not uc_called: if not uc_called:
unconfirmfun(txd, txid) reactor.callFromThread(unconfirmfun, txd, txid)
log.debug('saw confirmed tx before unconfirmed, ' + log.debug('saw confirmed tx before unconfirmed, ' +
'running unconfirmfun first') 'running unconfirmfun first')
confirmfun(txd, txid, txdata['confirmations']) reactor.callFromThread(confirmfun, txd, txid, txdata['confirmations'])
self.btcinterface.txnotify_fun.remove(txnotify_tuple) self.btcinterface.txnotify_fun.remove(txnotify_tuple)
log.debug('ran confirmfun') log.debug('ran confirmfun')

66
jmclient/test/test_tx_notify.py

@ -10,7 +10,8 @@ import subprocess
import jmbitcoin as bitcoin import jmbitcoin as bitcoin
import pytest import pytest
from jmclient import (load_program_config, jm_single, get_log, Wallet, sync_wallet) from jmclient import (load_program_config, jm_single, get_log, Wallet, sync_wallet)
from twisted.trial import unittest
from twisted.internet import reactor, task
log = get_log() log = get_log()
unconfirm_called = [False] unconfirm_called = [False]
@ -34,7 +35,11 @@ def timeout_callback(confirmed):
timeout_confirm_called[0] = True timeout_confirm_called[0] = True
log.debug('timeout confirm callback()') log.debug('timeout confirm callback()')
def test_notify_handler_errors(setup_tx_notify): def run_tests():
#TODO: rewrite with deferreds not callLater()
no_timeout()
def notify_handler_errors():
#TODO this has hardcoded 62612 which is from regtest_joinmarket.cfg #TODO this has hardcoded 62612 which is from regtest_joinmarket.cfg
#default testing config #default testing config
txhex = make_tx_add_notify() txhex = make_tx_add_notify()
@ -49,39 +54,32 @@ def test_notify_handler_errors(setup_tx_notify):
"http://localhost:62612/dummycommand"]) "http://localhost:62612/dummycommand"])
#alertnotifys with an alert message should be accepted (todo, deprecate) #alertnotifys with an alert message should be accepted (todo, deprecate)
res = subprocess.check_output(["curl", "-I", "--connect-timeout", "1", res = subprocess.check_output(["curl", "-I", "--connect-timeout", "1",
"http://localhost:62612/alertnotify?dummyalertmessage"]) "http://localhost:62612/alertnotify?dummyalertmessage"])
jm_single().bc_interface.tick_forward_chain_interval = 2
def test_no_timeout(setup_tx_notify): def no_timeout():
txhex = make_tx_add_notify() txhex = make_tx_add_notify()
jm_single().bc_interface.pushtx(txhex) jm_single().bc_interface.pushtx(txhex)
time.sleep(6) reactor.callLater(6, checkstate, True, True, False, False, unconfirm_timeout)
assert unconfirm_called[0]
assert confirm_called[0] def checkstate(uc, c, tu, tc, f=None):
assert not timeout_unconfirm_called[0] assert unconfirm_called[0] == uc
assert not timeout_confirm_called[0] assert confirm_called[0] == c
return True assert timeout_unconfirm_called[0] == tu
assert timeout_confirm_called[0] == tc
def test_unconfirm_timeout(setup_tx_notify): if f:
f()
def unconfirm_timeout():
txhex = make_tx_add_notify() txhex = make_tx_add_notify()
#dont pushtx #dont pushtx
time.sleep(6) reactor.callLater(6, checkstate, False, False, True, False)
assert not unconfirm_called[0]
assert not confirm_called[0] def confirm_timeout():
assert timeout_unconfirm_called[0]
assert not timeout_confirm_called[0]
return True
def test_confirm_timeout(setup_tx_notify):
txhex = make_tx_add_notify() txhex = make_tx_add_notify()
jm_single().bc_interface.tick_forward_chain_interval = -1 jm_single().bc_interface.tick_forward_chain_interval = -1
jm_single().bc_interface.pushtx(txhex) jm_single().bc_interface.pushtx(txhex)
time.sleep(10) reactor.callLater(True, False, False, True, notify_handler_errors)
jm_single().bc_interface.tick_forward_chain_interval = 2
assert unconfirm_called[0]
assert not confirm_called[0]
assert not timeout_unconfirm_called[0]
assert timeout_confirm_called[0]
return True
def make_tx_add_notify(): def make_tx_add_notify():
wallet_dict = make_wallets(1, [[1, 0, 0, 0, 0]], mean_amt=4, sdev_amt=0)[0] wallet_dict = make_wallets(1, [[1, 0, 0, 0, 0]], mean_amt=4, sdev_amt=0)[0]
@ -111,7 +109,19 @@ def make_tx_add_notify():
confirm_callback, output_addr, timeout_callback) confirm_callback, output_addr, timeout_callback)
return tx return tx
@pytest.fixture(scope="module") class TxNotifies(unittest.TestCase):
def setUp(self):
setup_tx_notify()
reactor.callLater(0.0, run_tests)
def test_waiter(self):
#TODO fixed timeout, horrible..
return task.deferLater(reactor, 30, self._called_by_deferred)
def _called_by_deferred(self):
pass
def setup_tx_notify(): def setup_tx_notify():
load_program_config() load_program_config()
jm_single().config.set('TIMEOUT', 'unconfirm_timeout_sec', '3') jm_single().config.set('TIMEOUT', 'unconfirm_timeout_sec', '3')

Loading…
Cancel
Save