diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -706,8 +706,10 @@ // actual payment and not change, this is a close match: it's the output // type we use subject to privacy issues, but not restricted by what // other software supports. - walletModel->wallet().learnRelatedScripts(newKey, g_change_type); - CTxDestination dest = GetDestinationForKey(newKey, g_change_type); + const OutputType change_type = + g_change_type != OutputType::NONE ? g_change_type : g_address_type; + walletModel->wallet().learnRelatedScripts(newKey, change_type); + CTxDestination dest = GetDestinationForKey(newKey, change_type); std::string label = tr("Refund from %1") .arg(recipient.authenticatedMerchant) .toStdString(); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -285,10 +285,10 @@ pwallet->TopUpKeyPool(); } - OutputType output_type = g_change_type; + OutputType output_type = + g_change_type != OutputType::NONE ? g_change_type : g_address_type; if (!request.params[0].isNull()) { - output_type = - ParseOutputType(request.params[0].get_str(), g_change_type); + output_type = ParseOutputType(request.params[0].get_str(), output_type); if (output_type == OutputType::NONE) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1010,6 +1010,8 @@ const std::string *account) const; Amount GetAvailableBalance(const CCoinControl *coinControl = nullptr) const; + OutputType TransactionChangeType(const std::vector &vecSend); + /** * Insert additional inputs into the transaction by calling * CreateTransaction(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2889,6 +2889,22 @@ return true; } +OutputType +CWallet::TransactionChangeType(const std::vector &vecSend) { + // If -changetype is specified, always use that change type. + if (g_change_type != OutputType::NONE) { + return g_change_type; + } + + // if g_address_type is legacy, use legacy address as change. + if (g_address_type == OutputType::LEGACY) { + return OutputType::LEGACY; + } + + // else use g_address_type for change + return g_address_type; +} + bool CWallet::CreateTransaction(const std::vector &vecSend, CTransactionRef &tx, CReserveKey &reservekey, Amount &nFeeRet, int &nChangePosInOut, @@ -2989,9 +3005,11 @@ return false; } - LearnRelatedScripts(vchPubKey, g_change_type); + const OutputType change_type = TransactionChangeType(vecSend); + + LearnRelatedScripts(vchPubKey, change_type); scriptChange = GetScriptForDestination( - GetDestinationForKey(vchPubKey, g_change_type)); + GetDestinationForKey(vchPubKey, change_type)); } CTxOut change_prototype_txout(Amount::zero(), scriptChange); coin_selection_params.change_output_size =