From 7c463780cf5339cd04a671b649305e834939070c Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 4 Nov 2016 23:23:48 -0700 Subject: [PATCH] Fixes #1779 so that sending to multiple zaddrs no longer fails. Commit 2eeb6b randomized the order of input and output notes, but this is now known to prevent the chaining of multiple joinsplits in a single transaction. The root cause has yet to be determined. This patch is a temporary fix and disables the shuffling of input and output notes. It also adds a chained joinsplit test to the python qa test suite. --- qa/rpc-tests/wallet_protectcoinbase.py | 17 +++++++++++++++++ src/primitives/transaction.cpp | 6 ++++-- src/wallet/asyncrpcoperation_sendmany.cpp | 5 ++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/wallet_protectcoinbase.py b/qa/rpc-tests/wallet_protectcoinbase.py index b3d554889..eabe26bf4 100755 --- a/qa/rpc-tests/wallet_protectcoinbase.py +++ b/qa/rpc-tests/wallet_protectcoinbase.py @@ -148,5 +148,22 @@ class Wallet2Test (BitcoinTestFramework): # check balance assert_equal(self.nodes[2].getbalance(), 9) + # Check that chained joinsplits in a single tx are created successfully. + recipients = [] + num_recipients = 3 + amount_per_recipient = Decimal('0.002') + for i in xrange(0,num_recipients): + newzaddr = self.nodes[2].z_getnewaddress() + recipients.append({"address":newzaddr, "amount":amount_per_recipient}) + myopid = self.nodes[0].z_sendmany(myzaddr, recipients) + self.wait_for_operationd_success(myopid) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # check balances + resp = self.nodes[2].z_gettotalbalance() + assert_equal(Decimal(resp["private"]), num_recipients * amount_per_recipient) + if __name__ == '__main__': Wallet2Test ().main () diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 399cd665a..de722eb92 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -57,8 +57,10 @@ JSDescription JSDescription::Randomized( // Randomize the order of the inputs and outputs inputMap = {0, 1}; outputMap = {0, 1}; - MappedShuffle(inputs.begin(), inputMap.begin(), ZC_NUM_JS_INPUTS, gen); - MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen); + if (gen) { + MappedShuffle(inputs.begin(), inputMap.begin(), ZC_NUM_JS_INPUTS, gen); + MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen); + } return JSDescription( params, pubKeyHash, anchor, inputs, outputs, diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index f72badc60..fa359206f 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -875,6 +875,7 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit( {info.vjsout[0], info.vjsout[1]}; boost::array inputMap; boost::array outputMap; + std::function emptyFunc; JSDescription jsdesc = JSDescription::Randomized( *pzcashParams, joinSplitPubKey_, @@ -885,7 +886,9 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit( outputMap, info.vpub_old, info.vpub_new, - !this->testmode); + !this->testmode, + // Temporary fix for #1779 is to disable shuffling of inputs and outputs. + emptyFunc); if (!(jsdesc.Verify(*pzcashParams, joinSplitPubKey_))) { throw std::runtime_error("error verifying joinsplit");