diff --git a/src/gtest/test_random.cpp b/src/gtest/test_random.cpp index 61f81c33..d89702bc 100644 --- a/src/gtest/test_random.cpp +++ b/src/gtest/test_random.cpp @@ -24,4 +24,12 @@ TEST(Random, MappedShuffle) { std::vector em2 {0, 1, 2, 3, 4}; EXPECT_EQ(ea2, a2); EXPECT_EQ(em2, m2); + + auto a3 = a; + auto m3 = m; + MappedShuffle(a3.begin(), m3.begin(), a3.size(), GenIdentity); + std::vector ea3 {8, 4, 6, 3, 5}; + std::vector em3 {0, 1, 2, 3, 4}; + EXPECT_EQ(ea3, a3); + EXPECT_EQ(em3, m3); } diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index de722eb9..d1e96936 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -57,10 +57,11 @@ JSDescription JSDescription::Randomized( // Randomize the order of the inputs and outputs inputMap = {0, 1}; outputMap = {0, 1}; - if (gen) { - MappedShuffle(inputs.begin(), inputMap.begin(), ZC_NUM_JS_INPUTS, gen); - MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen); - } + + assert(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/random.cpp b/src/random.cpp index 0ba0de90..4f197fca 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -137,3 +137,8 @@ void seed_insecure_rand(bool fDeterministic) insecure_rand_Rw = tmp; } } + +int GenIdentity(int n) +{ + return n-1; +} diff --git a/src/random.h b/src/random.h index 1f6f7fef..5bc8b548 100644 --- a/src/random.h +++ b/src/random.h @@ -25,6 +25,11 @@ uint64_t GetRand(uint64_t nMax); int GetRandInt(int nMax); uint256 GetRandHash(); +/** + * Identity function for MappedShuffle, so that elements retain their original order. + */ + int GenIdentity(int n); + /** * Rearranges the elements in the range [first,first+len) randomly, assuming * that gen is a uniform random number generator. Follows the same algorithm as diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index fa359206..7f9549b7 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -875,7 +875,6 @@ 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_, @@ -888,7 +887,7 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit( info.vpub_new, !this->testmode, // Temporary fix for #1779 is to disable shuffling of inputs and outputs. - emptyFunc); + GenIdentity); if (!(jsdesc.Verify(*pzcashParams, joinSplitPubKey_))) { throw std::runtime_error("error verifying joinsplit");