[wallet] use P2WPKH change output if any destination is P2WPKH or P2WSH

Only if -changetype is not set and -addresstype is not "legacy".
This commit is contained in:
Sjors Provoost
2018-01-23 17:56:15 +01:00
parent 44080a90a2
commit 596c44633f
6 changed files with 154 additions and 24 deletions

View File

@@ -2644,6 +2644,34 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
return true;
}
OutputType CWallet::TransactionChangeType(const std::vector<CRecipient>& vecSend)
{
// If -changetype is specified, always use that change type.
if (g_change_type != OUTPUT_TYPE_NONE) {
return g_change_type;
}
// if g_address_type is legacy, use legacy address as change (even
// if some of the outputs are P2WPKH or P2WSH).
if (g_address_type == OUTPUT_TYPE_LEGACY) {
return OUTPUT_TYPE_LEGACY;
}
// if any destination is P2WPKH or P2WSH, use P2WPKH for the change
// output.
for (const auto& recipient : vecSend) {
// Check if any destination contains a witness program:
int witnessversion = 0;
std::vector<unsigned char> witnessprogram;
if (recipient.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
return OUTPUT_TYPE_BECH32;
}
}
// else use g_address_type for change
return g_address_type;
}
bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign)
{
@@ -2739,8 +2767,10 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
return false;
}
LearnRelatedScripts(vchPubKey, g_change_type);
scriptChange = GetScriptForDestination(GetDestinationForKey(vchPubKey, g_change_type));
const OutputType change_type = TransactionChangeType(vecSend);
LearnRelatedScripts(vchPubKey, change_type);
scriptChange = GetScriptForDestination(GetDestinationForKey(vchPubKey, change_type));
}
CTxOut change_prototype_txout(0, scriptChange);
size_t change_prototype_size = GetSerializeSize(change_prototype_txout, SER_DISK, 0);