From 15089fcf53194c4242dbd35cae8c0d617428a669 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Mon, 7 Jun 2021 22:51:47 +0100 Subject: [PATCH 1/2] Fix additionalfeeoutputindex check in BIP78 Before this commit, if the sender specified the additionalfeeoutputindex as 0, the receiver incorrectly treated this as meaning it could not decrement the change value at all (treating zero as false in Python `if`), meaning that the feerate was reduced more than intended, or in extreme cases, the payjoin fell back incorrectly because the feerate fell below the specified minfeerate. After this commit, the additionalfeeoutputindex value specified by the sender is correctly used by the receiver in all cases. --- jmclient/jmclient/payjoin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jmclient/jmclient/payjoin.py b/jmclient/jmclient/payjoin.py index 4d90b2f..f77314a 100644 --- a/jmclient/jmclient/payjoin.py +++ b/jmclient/jmclient/payjoin.py @@ -735,7 +735,7 @@ class PayjoinConverter(object): return (False, "Invalid request parameters.", "original-psbt-rejected") - if afoi and not (self.manager.change_out_index == afoi): + if afoi is not None and not (self.manager.change_out_index == afoi): return (False, "additionalfeeoutputindex is " "not the change output. Joinmarket does " "not currently support this.", @@ -817,7 +817,7 @@ class PayjoinConverter(object): # set the intended virtual size of our input: vsize = self.manager.get_vsize_for_input() our_fee_bump = 0 - if afoi: + if afoi is not None: # We plan to reduce the change_out by a fee contribution. # Calculate the additional fee we think we need for our input, # to keep the same feerate as the original transaction (this also From c70f25388cc2a85cf9751c5a8de6b85bbdaa8152 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Tue, 8 Jun 2021 15:33:32 +0100 Subject: [PATCH 2/2] add test case for low feerate --- jmclient/test/test_payjoin.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/jmclient/test/test_payjoin.py b/jmclient/test/test_payjoin.py index 7ae8526..9def036 100644 --- a/jmclient/test/test_payjoin.py +++ b/jmclient/test/test_payjoin.py @@ -145,6 +145,16 @@ class TrialTestPayjoin3(PayjoinTestBase, unittest.TestCase): self.wallet_structure = [3, 1, 0, 0, 0] return self.do_test_payment(SegwitWallet, SegwitWallet, amt=4.5) +class TrialTestPayjoin4(PayjoinTestBase, unittest.TestCase): + def reset_fee(self, res): + jm_single().config.set("POLICY", "txfees", self.old_txfees) + def test_low_feerate(self): + self.old_txfees = jm_single().config.get("POLICY", "tx_fees") + jm_single().config.set("POLICY", "tx_fees", "1300") + d = self.do_test_payment(SegwitWallet, SegwitWallet) + d.addCallback(self.reset_fee) + return d + def bip78_receiver_response(response, manager): d = readBody(response) # if the response code is not 200 OK, we must assume payjoin