Browse Source

catch connection lost failures in default errbacks for daemon and client

master
Adam Gibson 9 years ago
parent
commit
473cf2e217
No known key found for this signature in database
GPG Key ID: B3AE09F1E9A3197A
  1. 26
      jmclient/client_protocol.py
  2. 28
      scripts/joinmarketd.py

26
jmclient/client_protocol.py

@ -3,6 +3,9 @@ from __future__ import print_function
from twisted.python.log import startLogging, err from twisted.python.log import startLogging, err
from twisted.internet import protocol, reactor from twisted.internet import protocol, reactor
from twisted.internet.task import LoopingCall from twisted.internet.task import LoopingCall
from twisted.internet.error import (ConnectionLost, ConnectionAborted,
ConnectionClosed, ConnectionDone)
from twisted.python import failure
from twisted.protocols import amp from twisted.protocols import amp
from twisted.internet.protocol import ClientFactory from twisted.internet.protocol import ClientFactory
from twisted.internet.endpoints import TCP4ClientEndpoint from twisted.internet.endpoints import TCP4ClientEndpoint
@ -57,6 +60,13 @@ class JMTakerClientProtocol(amp.AMP):
if 'accepted' not in response or not response['accepted']: if 'accepted' not in response or not response['accepted']:
reactor.stop() reactor.stop()
def defaultErrback(self, failure):
failure.trap(ConnectionAborted, ConnectionClosed, ConnectionDone, ConnectionLost)
def defaultCallbacks(self, d):
d.addCallback(self.checkClientResponse)
d.addErrback(self.defaultErrback)
def connectionMade(self): def connectionMade(self):
self.factory.setClient(self) self.factory.setClient(self)
self.clientStart() self.clientStart()
@ -80,7 +90,7 @@ class JMTakerClientProtocol(amp.AMP):
irc_configs=json.dumps(irc_configs), irc_configs=json.dumps(irc_configs),
minmakers=minmakers, minmakers=minmakers,
maker_timeout_sec=maker_timeout_sec) maker_timeout_sec=maker_timeout_sec)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
def set_nick(self): def set_nick(self):
self.nick_pubkey = btc.privtopub(self.nick_priv) self.nick_pubkey = btc.privtopub(self.nick_priv)
@ -108,7 +118,7 @@ class JMTakerClientProtocol(amp.AMP):
self.set_nick() self.set_nick()
d = self.callRemote(commands.JMStartMC, d = self.callRemote(commands.JMStartMC,
nick=self.nick) nick=self.nick)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
return {'accepted': True} return {'accepted': True}
@commands.JMUp.responder @commands.JMUp.responder
@ -116,7 +126,7 @@ class JMTakerClientProtocol(amp.AMP):
d = self.callRemote(commands.JMSetup, d = self.callRemote(commands.JMSetup,
role="TAKER", role="TAKER",
n_counterparties=4) #TODO this number should be set n_counterparties=4) #TODO this number should be set
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
return {'accepted': True} return {'accepted': True}
@commands.JMSetupDone.responder @commands.JMSetupDone.responder
@ -167,7 +177,7 @@ class JMTakerClientProtocol(amp.AMP):
commitment=str(cmt), commitment=str(cmt),
revelation=str(rev), revelation=str(rev),
filled_offers=json.dumps(foffers)) filled_offers=json.dumps(foffers))
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
return {'accepted': True} return {'accepted': True}
@commands.JMSigReceived.responder @commands.JMSigReceived.responder
@ -188,7 +198,7 @@ class JMTakerClientProtocol(amp.AMP):
cmd=cmd, cmd=cmd,
msg_to_return=msg_to_return, msg_to_return=msg_to_return,
hostid=hostid) hostid=hostid)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
return {'accepted': True} return {'accepted': True}
@commands.JMRequestMsgSigVerify.responder @commands.JMRequestMsgSigVerify.responder
@ -214,18 +224,18 @@ class JMTakerClientProtocol(amp.AMP):
nick=nick, nick=nick,
fullmsg=fullmsg, fullmsg=fullmsg,
hostid=hostid) hostid=hostid)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
return {'accepted': True} return {'accepted': True}
def get_offers(self): def get_offers(self):
d = self.callRemote(commands.JMRequestOffers) d = self.callRemote(commands.JMRequestOffers)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
def make_tx(self, nick_list, txhex): def make_tx(self, nick_list, txhex):
d = self.callRemote(commands.JMMakeTx, d = self.callRemote(commands.JMMakeTx,
nick_list= json.dumps(nick_list), nick_list= json.dumps(nick_list),
txhex=txhex) txhex=txhex)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
class JMTakerClientProtocolFactory(protocol.ClientFactory): class JMTakerClientProtocolFactory(protocol.ClientFactory):

28
scripts/joinmarketd.py

@ -12,7 +12,9 @@ from twisted.protocols import amp
from twisted.internet import reactor from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory from twisted.internet.protocol import ServerFactory
from twisted.python.log import startLogging, err from twisted.python.log import startLogging, err
from twisted.python import log from twisted.internet.error import (ConnectionLost, ConnectionAborted,
ConnectionClosed, ConnectionDone)
from twisted.python import failure, log
import json import json
import time import time
import threading import threading
@ -62,6 +64,13 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
if 'accepted' not in response or not response['accepted']: if 'accepted' not in response or not response['accepted']:
reactor.stop() reactor.stop()
def defaultErrback(self, failure):
failure.trap(ConnectionAborted, ConnectionClosed, ConnectionDone, ConnectionLost)
def defaultCallbacks(self, d):
d.addCallback(self.checkClientResponse)
d.addErrback(self.defaultErrback)
@JMInit.responder @JMInit.responder
def on_JM_INIT(self, bcsource, network, irc_configs, minmakers, def on_JM_INIT(self, bcsource, network, irc_configs, minmakers,
maker_timeout_sec): maker_timeout_sec):
@ -101,7 +110,7 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
nick_max_encoded=NICK_MAX_ENCODED, nick_max_encoded=NICK_MAX_ENCODED,
joinmarket_nick_header=JOINMARKET_NICK_HEADER, joinmarket_nick_header=JOINMARKET_NICK_HEADER,
joinmarket_version=JM_VERSION) joinmarket_version=JM_VERSION)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
return {'accepted': True} return {'accepted': True}
@JMStartMC.responder @JMStartMC.responder
@ -129,7 +138,7 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
"""Fired when channel indicated state readiness """Fired when channel indicated state readiness
""" """
d = self.callRemote(JMUp) d = self.callRemote(JMUp)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
@JMSetup.responder @JMSetup.responder
def on_JM_SETUP(self, role, n_counterparties): def on_JM_SETUP(self, role, n_counterparties):
@ -142,7 +151,7 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
self.kp = init_keypair() self.kp = init_keypair()
print("Received setup command") print("Received setup command")
d = self.callRemote(JMSetupDone) d = self.callRemote(JMSetupDone)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
#Request orderbook here, on explicit setup request from client, #Request orderbook here, on explicit setup request from client,
#assumes messagechannels are in "up" state. Orders are read #assumes messagechannels are in "up" state. Orders are read
#in the callback on_order_seen in OrderbookWatch. #in the callback on_order_seen in OrderbookWatch.
@ -160,7 +169,7 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
string_orderbook = json.dumps(self.orderbook[:100]) string_orderbook = json.dumps(self.orderbook[:100])
d = self.callRemote(JMOffers, d = self.callRemote(JMOffers,
orderbook=string_orderbook) orderbook=string_orderbook)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
return {'accepted': True} return {'accepted': True}
@JMFill.responder @JMFill.responder
@ -218,11 +227,12 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
ioauth_data = json.dumps(self.ioauth_data)) ioauth_data = json.dumps(self.ioauth_data))
if not accepted: if not accepted:
#Client simply accepts failure TODO #Client simply accepts failure TODO
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
else: else:
#Act differently if *we* provided utxos, but #Act differently if *we* provided utxos, but
#client does not accept for some reason #client does not accept for some reason
d.addCallback(self.checkUtxosAccepted) d.addCallback(self.checkUtxosAccepted)
d.addErrback(self.defaultErrback)
def completeStage1(self): def completeStage1(self):
"""Timeout of stage 1 requests; """Timeout of stage 1 requests;
@ -251,7 +261,7 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
d = self.callRemote(JMSigReceived, d = self.callRemote(JMSigReceived,
nick=nick, nick=nick,
sig=sig) sig=sig)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
"""The following functions handle requests and responses """The following functions handle requests and responses
from client for messaging signing and verifying. from client for messaging signing and verifying.
@ -271,7 +281,7 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
msg=str(msg), msg=str(msg),
msg_to_be_signed=str(msg_to_be_signed), msg_to_be_signed=str(msg_to_be_signed),
hostid=str(hostid)) hostid=str(hostid))
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
def request_signature_verify(self, msg, fullmsg, sig, pubkey, nick, hashlen, def request_signature_verify(self, msg, fullmsg, sig, pubkey, nick, hashlen,
max_encoded, hostid): max_encoded, hostid):
@ -285,7 +295,7 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
hashlen=hashlen, hashlen=hashlen,
max_encoded=max_encoded, max_encoded=max_encoded,
hostid=hostid) hostid=hostid)
d.addCallback(self.checkClientResponse) self.defaultCallbacks(d)
@JMMsgSignature.responder @JMMsgSignature.responder
def on_JM_MSGSIGNATURE(self, nick, cmd, msg_to_return, hostid): def on_JM_MSGSIGNATURE(self, nick, cmd, msg_to_return, hostid):

Loading…
Cancel
Save