@@ -117,16 +117,26 @@ def recv_txio(self, nick, utxo_list, cj_pub, change_addr):
117117 log .debug (('ERROR outputs unconfirmed or already spent. '
118118 'utxo_data={}' ).format (pprint .pformat (utxo_data )))
119119 # when internal reviewing of makers is created, add it here to
120- # immediately quit
120+ # immediately quit; currently, the timeout thread suffices.
121121 return
122122
123- # ignore this message, eventually the timeout thread will recover
124123 total_input = sum ([d ['value' ] for d in utxo_data ])
125124 real_cjfee = calc_cj_fee (order ['ordertype' ], order ['cjfee' ],
126125 self .cj_amount )
127- self .outputs .append ({'address' : change_addr ,
128- 'value' : total_input - self .cj_amount - order [
129- 'txfee' ] + real_cjfee })
126+ change_amount = total_input - self .cj_amount - order [
127+ 'txfee' ] + real_cjfee
128+
129+ # certain malicious and/or incompetent liquidity providers send
130+ # inputs totalling less than the coinjoin amount! this leads to
131+ # a change output of zero satoshis, so the invalid transaction
132+ # fails harmlessly; let's fail earlier, with a clear message.
133+ if change_amount < jm_single ().DUST_THRESHOLD :
134+ fmt = ('ERROR counterparty requires sub-dust change. nick={}'
135+ 'totalin={:d} cjamount={:d} change={:d}' ).format
136+ log .debug (fmt (nick , total_input , self .cj_amount , change_amount ))
137+ return # timeout marks this maker as nonresponsive
138+
139+ self .outputs .append ({'address' : change_addr , 'value' : change_amount })
130140 fmt = ('fee breakdown for {} totalin={:d} '
131141 'cjamount={:d} txfee={:d} realcjfee={:d}' ).format
132142 log .debug (fmt (nick , total_input , self .cj_amount ,
0 commit comments