# Buggy code
def on_auth_received(self, nick, offer, commitment, cr, amount, kphex):
    """Receives data on proposed transaction offer from daemon, verifies
    commitment, returns necessary data to send ioauth message (utxos etc)
    """
    # deserialize the commitment revelation
    cr_dict = PoDLE.deserialize_revelation(cr)
    # check the validity of the proof of discrete log equivalence
    tries = jm_single().config.getint("POLICY", "taker_utxo_retries")

    def reject(msg):
        jlog.info("Counterparty commitment not accepted, reason: " + msg)
        return (False,)

    if not verify_podle(
        str(cr_dict["P"]),
        str(cr_dict["P2"]),
        str(cr_dict["sig"]),
        str(cr_dict["e"]),
        str(commitment),
        index_range=range(tries),
    ):
        reason = "verify_podle failed"
        return reject(reason)
    # finally, check that the proffered utxo is real, old enough, large enough,
    # and corresponds to the pubkey
    res = jm_single().bc_interface.query_utxo_set([cr_dict["utxo"]], includeconf=True)
    if len(res) != 1 or not res[0]:
        reason = "authorizing utxo is not valid"
        return reject(reason)
    age = jm_single().config.getint("POLICY", "taker_utxo_age")
    if res[0]["confirms"] < age:
        reason = "commitment utxo not old enough: " + str(res[0]["confirms"])
        return reject(reason)
    reqd_amt = int(
        amount * jm_single().config.getint("POLICY", "taker_utxo_amtpercent") / 100.0
    )
    if res[0]["value"] < reqd_amt:
        reason = "commitment utxo too small: " + str(res[0]["value"])
        return reject(reason)

    # FIXME: This only works if taker's commitment address is of same type
    # as our wallet.
    if res[0]["address"] != self.wallet.pubkey_to_addr(unhexlify(cr_dict["P"])):
        reason = "Invalid podle pubkey: " + str(cr_dict["P"])
        return reject(reason)

    # authorisation of taker passed
    # Find utxos for the transaction now:
    utxos, cj_addr, change_addr = self.oid_to_order(offer, amount)
    if not utxos:
        # could not find funds
        return (False,)
    self.wallet.update_cache_index()
    # Construct data for auth request back to taker.
    # Need to choose an input utxo pubkey to sign with
    # (no longer using the coinjoin pubkey from 0.2.0)
    # Just choose the first utxo in self.utxos and retrieve key from wallet.
    auth_address = utxos[utxos.keys()[0]]["address"]
    auth_key = self.wallet.get_key_from_addr(auth_address)
    auth_pub = btc.privtopub(auth_key)
    btc_sig = btc.ecdsa_sign(kphex, auth_key)
    return (True, utxos, auth_pub, cj_addr, change_addr, btc_sig)


# Traceback (jmclient.podle.PoDLEError)
Unhandled Error
Traceback (most recent call last):
File "XXX/joinmarket-clientserver/jmvenv/lib/python2.7/site-packages/twisted/protocols/amp.py", line 1043, in _commandReceived
deferred = self.dispatchCommand(box)
File "XXX/joinmarket-clientserver/jmvenv/lib/python2.7/site-packages/twisted/protocols/amp.py", line 1101, in dispatchCommand
return maybeDeferred(responder, box)
File "XXX/joinmarket-clientserver/jmvenv/lib/python2.7/site-packages/twisted/internet/defer.py", line 150, in maybeDeferred
result = f(*args, **kw)
File "XXX/joinmarket-clientserver/jmvenv/lib/python2.7/site-packages/twisted/protocols/amp.py", line 1188, in doit
return maybeDeferred(aCallable, **kw).addCallback(
--- <exception caught here> ---
File "XXX/joinmarket-clientserver/jmvenv/lib/python2.7/site-packages/twisted/internet/defer.py", line 150, in maybeDeferred
result = f(*args, **kw)
File "XXX/joinmarket-clientserver/jmvenv/lib/python2.7/site-packages/jmclient/client_protocol.py", line 194, in on_JM_AUTH_RECEIVED
commitment, revelation, amount, kphex)
File "XXX/joinmarket-clientserver/jmvenv/lib/python2.7/site-packages/jmclient/maker.py", line 51, in on_auth_received
cr_dict = PoDLE.deserialize_revelation(cr)
File "XXX/joinmarket-clientserver/jmvenv/lib/python2.7/site-packages/jmclient/podle.py", line 211, in deserialize_revelation
raise PoDLEError("Failed to deserialize, wrong format")
jmclient.podle.PoDLEError: Failed to deserialize, wrong format

Amp server or network failure unhandled by client application.  Dropping connection!  To avoid, add errbacks to ALL remote commands!
Traceback (most recent call last):
Failure: twisted.protocols.amp.UnknownRemoteError: Code<UNKNOWN>: Unknown Error

# Fixed code
def on_auth_received(self, nick, offer, commitment, cr, amount, kphex):
    """Receives data on proposed transaction offer from daemon, verifies
    commitment, returns necessary data to send ioauth message (utxos etc)
    """
    # check the validity of the proof of discrete log equivalence
    tries = jm_single().config.getint("POLICY", "taker_utxo_retries")

    def reject(msg):
        jlog.info("Counterparty commitment not accepted, reason: " + msg)
        return (False,)

    # deserialize the commitment revelation
    try:
        cr_dict = PoDLE.deserialize_revelation(cr)
    except PoDLEError as e:
        reason = repr(e)
        return reject(reason)

    if not verify_podle(
        str(cr_dict["P"]),
        str(cr_dict["P2"]),
        str(cr_dict["sig"]),
        str(cr_dict["e"]),
        str(commitment),
        index_range=range(tries),
    ):
        reason = "verify_podle failed"
        return reject(reason)
    # finally, check that the proffered utxo is real, old enough, large enough,
    # and corresponds to the pubkey
    res = jm_single().bc_interface.query_utxo_set([cr_dict["utxo"]], includeconf=True)
    if len(res) != 1 or not res[0]:
        reason = "authorizing utxo is not valid"
        return reject(reason)
    age = jm_single().config.getint("POLICY", "taker_utxo_age")
    if res[0]["confirms"] < age:
        reason = "commitment utxo not old enough: " + str(res[0]["confirms"])
        return reject(reason)
    reqd_amt = int(
        amount * jm_single().config.getint("POLICY", "taker_utxo_amtpercent") / 100.0
    )
    if res[0]["value"] < reqd_amt:
        reason = "commitment utxo too small: " + str(res[0]["value"])
        return reject(reason)

    # FIXME: This only works if taker's commitment address is of same type
    # as our wallet.
    if res[0]["address"] != self.wallet.pubkey_to_addr(unhexlify(cr_dict["P"])):
        reason = "Invalid podle pubkey: " + str(cr_dict["P"])
        return reject(reason)

    # authorisation of taker passed
    # Find utxos for the transaction now:
    utxos, cj_addr, change_addr = self.oid_to_order(offer, amount)
    if not utxos:
        # could not find funds
        return (False,)
    self.wallet.update_cache_index()
    # Construct data for auth request back to taker.
    # Need to choose an input utxo pubkey to sign with
    # (no longer using the coinjoin pubkey from 0.2.0)
    # Just choose the first utxo in self.utxos and retrieve key from wallet.
    auth_address = utxos[utxos.keys()[0]]["address"]
    auth_key = self.wallet.get_key_from_addr(auth_address)
    auth_pub = btc.privtopub(auth_key)
    btc_sig = btc.ecdsa_sign(kphex, auth_key)
    return (True, utxos, auth_pub, cj_addr, change_addr, btc_sig)