Browse Source

Randomize JoinSplits in z_sendmany

pull/4/head
Jack Grigg 8 years ago
parent
commit
2eeb6bebde
No known key found for this signature in database GPG Key ID: 6A6914DAFBEA00DA
  1. 54
      src/wallet/asyncrpcoperation_sendmany.cpp

54
src/wallet/asyncrpcoperation_sendmany.cpp

@ -29,6 +29,22 @@
using namespace libzcash;
int find_output(Object obj, int n) {
Value outputMapValue = find_value(obj, "outputmap");
if (outputMapValue.type() != array_type) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing outputmap for JoinSplit operation");
}
Array outputMap = outputMapValue.get_array();
for (size_t i = 0; i < outputMap.size(); i++) {
if (outputMap[i] == n) {
return i;
}
}
return -1;
}
AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
std::string fromAddress,
std::vector<SendManyRecipient> tOutputs,
@ -372,6 +388,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
*/
Object obj;
CAmount jsChange = 0; // this is updated after each joinsplit
int changeOutputIndex = -1; // this is updated after each joinsplit if jsChange > 0
bool minersFeeProcessed = false;
if (t_outputs_total > 0) {
@ -429,6 +446,10 @@ bool AsyncRPCOperation_sendmany::main_impl() {
}
obj = perform_joinsplit(info, outPoints);
if (jsChange > 0) {
changeOutputIndex = find_output(obj, 1);
}
}
}
@ -442,9 +463,6 @@ bool AsyncRPCOperation_sendmany::main_impl() {
// Keep track of treestate within this transaction
boost::unordered_map<uint256, ZCIncrementalMerkleTree, CCoinsKeyHasher> intermediates;
std::vector<uint256> previousCommitments;
// NOTE: Randomization of input and output order could break this in future
const int changeOutputIndex = 1;
while (zOutputsDeque.size() > 0) {
AsyncJoinSplitInfo info;
@ -645,6 +663,10 @@ bool AsyncRPCOperation_sendmany::main_impl() {
}
obj = perform_joinsplit(info, witnesses, jsAnchor);
if (jsChange > 0) {
changeOutputIndex = find_output(obj, 1);
}
}
}
@ -845,11 +867,20 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit(
);
// Generate the proof, this can take over a minute.
JSDescription jsdesc(*pzcashParams,
boost::array<libzcash::JSInput, ZC_NUM_JS_INPUTS> inputs
{info.vjsin[0], info.vjsin[1]};
boost::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> outputs
{info.vjsout[0], info.vjsout[1]};
boost::array<size_t, ZC_NUM_JS_INPUTS> inputMap;
boost::array<size_t, ZC_NUM_JS_OUTPUTS> outputMap;
JSDescription jsdesc = JSDescription::Randomized(
*pzcashParams,
joinSplitPubKey_,
anchor,
{info.vjsin[0], info.vjsin[1]},
{info.vjsout[0], info.vjsout[1]},
inputs,
outputs,
inputMap,
outputMap,
info.vpub_old,
info.vpub_new,
!this->testmode);
@ -910,10 +941,21 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit(
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
}
Array arrInputMap;
Array arrOutputMap;
for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) {
arrInputMap.push_back(inputMap[i]);
}
for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) {
arrOutputMap.push_back(outputMap[i]);
}
Object obj;
obj.push_back(Pair("encryptednote1", encryptedNote1));
obj.push_back(Pair("encryptednote2", encryptedNote2));
obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end())));
obj.push_back(Pair("inputmap", arrInputMap));
obj.push_back(Pair("outputmap", arrOutputMap));
return obj;
}

Loading…
Cancel
Save