Skip to content

Commit 253cd7e

Browse files
committed
Only reserve key for scriptChange once in CreateTransaction
This does not affect behavior but allows us to have access to an output to scriptChange even if we currently do not have change in the transaction.
1 parent ca4c545 commit 253cd7e

File tree

1 file changed

+34
-33
lines changed

1 file changed

+34
-33
lines changed

src/wallet/wallet.cpp

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2569,6 +2569,38 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
25692569
std::vector<COutput> vAvailableCoins;
25702570
AvailableCoins(vAvailableCoins, true, coinControl);
25712571

2572+
// Create change script that will be used if we need change
2573+
// TODO: pass in scriptChange instead of reservekey so
2574+
// change transaction isn't always pay-to-bitcoin-address
2575+
CScript scriptChange;
2576+
2577+
// coin control: send change to custom address
2578+
if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
2579+
scriptChange = GetScriptForDestination(coinControl->destChange);
2580+
2581+
// no coin control: send change to newly generated address
2582+
else
2583+
{
2584+
// Note: We use a new key here to keep it from being obvious which side is the change.
2585+
// The drawback is that by not reusing a previous key, the change may be lost if a
2586+
// backup is restored, if the backup doesn't have the new private key for the change.
2587+
// If we reused the old key, it would be possible to add code to look for and
2588+
// rediscover unknown transactions that were written with keys of ours to recover
2589+
// post-backup change.
2590+
2591+
// Reserve a new key pair from key pool
2592+
CPubKey vchPubKey;
2593+
bool ret;
2594+
ret = reservekey.GetReservedKey(vchPubKey, true);
2595+
if (!ret)
2596+
{
2597+
strFailReason = _("Keypool ran out, please call keypoolrefill first");
2598+
return false;
2599+
}
2600+
2601+
scriptChange = GetScriptForDestination(vchPubKey.GetID());
2602+
}
2603+
25722604
nFeeRet = 0;
25732605
// Start with no fee and loop until there is enough fee
25742606
while (true)
@@ -2627,37 +2659,6 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
26272659
if (nChange > 0)
26282660
{
26292661
// Fill a vout to ourself
2630-
// TODO: pass in scriptChange instead of reservekey so
2631-
// change transaction isn't always pay-to-bitcoin-address
2632-
CScript scriptChange;
2633-
2634-
// coin control: send change to custom address
2635-
if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
2636-
scriptChange = GetScriptForDestination(coinControl->destChange);
2637-
2638-
// no coin control: send change to newly generated address
2639-
else
2640-
{
2641-
// Note: We use a new key here to keep it from being obvious which side is the change.
2642-
// The drawback is that by not reusing a previous key, the change may be lost if a
2643-
// backup is restored, if the backup doesn't have the new private key for the change.
2644-
// If we reused the old key, it would be possible to add code to look for and
2645-
// rediscover unknown transactions that were written with keys of ours to recover
2646-
// post-backup change.
2647-
2648-
// Reserve a new key pair from key pool
2649-
CPubKey vchPubKey;
2650-
bool ret;
2651-
ret = reservekey.GetReservedKey(vchPubKey, true);
2652-
if (!ret)
2653-
{
2654-
strFailReason = _("Keypool ran out, please call keypoolrefill first");
2655-
return false;
2656-
}
2657-
2658-
scriptChange = GetScriptForDestination(vchPubKey.GetID());
2659-
}
2660-
26612662
CTxOut newTxOut(nChange, scriptChange);
26622663

26632664
// Never create dust outputs; if we would, just
@@ -2666,7 +2667,6 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
26662667
{
26672668
nChangePosInOut = -1;
26682669
nFeeRet += nChange;
2669-
reservekey.ReturnKey();
26702670
}
26712671
else
26722672
{
@@ -2685,7 +2685,6 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
26852685
txNew.vout.insert(position, newTxOut);
26862686
}
26872687
} else {
2688-
reservekey.ReturnKey();
26892688
nChangePosInOut = -1;
26902689
}
26912690

@@ -2777,6 +2776,8 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
27772776
}
27782777
}
27792778

2779+
if (nChangePosInOut == -1) reservekey.ReturnKey(); // Return any reserved key if we don't have change
2780+
27802781
if (sign)
27812782
{
27822783
CTransaction txNewConst(txNew);

0 commit comments

Comments
 (0)