From b7d7b2ad9d03061a682d6de6881f44a52a6cb84d Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 21 Aug 2016 23:57:12 -0700 Subject: [PATCH] z_sendmany from a taddr now routes change to a new address instead of back to the sender's taddr, --- src/wallet/asyncrpcoperation_sendmany.cpp | 13 +++++++++++-- src/wallet/rpcwallet.cpp | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index e3fc1e4ed..a814af66c 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -292,7 +292,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { // Miners fee will be consumed from the value pool fundsSpent += minersFee; - // Change will flow back to sender address + // Private change will flow back to sender's zaddr, while transparent change flows to a new taddr. CAmount change = funds - fundsSpent; if (change < 0) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strprintf("Insufficient funds or internal error, spent too much leaving negative change %ld", change)); @@ -301,7 +301,16 @@ bool AsyncRPCOperation_sendmany::main_impl() { info.vjsout.push_back(JSOutput(frompaymentaddress_, change)); } else if (isfromtaddr_) { CMutableTransaction rawTx(tx_); - CScript scriptPubKey = GetScriptForDestination(fromtaddr_.Get()); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + CReserveKey keyChange(pwalletMain); + CPubKey vchPubKey; + bool ret = keyChange.GetReservedKey(vchPubKey); + if (!ret) + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Could not generate a taddr to use as a change address"); // should never fail, as we just unlocked + CScript scriptPubKey = GetScriptForDestination(vchPubKey.GetID()); CTxOut out(change, scriptPubKey); rawTx.vout.push_back(out); tx_ = CTransaction(rawTx); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4c3578e1a..a2e2e9d11 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2870,7 +2870,6 @@ Value z_getoperationstatus(const Array& params, bool fHelp) return status; } -// If there is any change, it will flow back to the source taddr or zaddr. Value z_sendmany(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) @@ -2881,6 +2880,7 @@ Value z_sendmany(const Array& params, bool fHelp) "z_sendmany \"fromaddress\" [{\"address\":... ,\"amount\":...},...] ( minconf )\n" "\n*** This alpha release supports multiple recipients, but only one of them can be a zaddr ***" "\nSend multiple times. Amounts are double-precision floating point numbers." + "\nChange from a taddr flows to a new taddr address, while change from zaddr returns to itself." + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"fromaddress\" (string, required) The taddr or zaddr to send the funds from.\n"