Skip to content

Commit 3f9e746

Browse files
committed
[Wallet] Combine change to output when possible & provide it in autocombine
-When a change address is specified through coincontrol and this adress is already receiving an output, we now add the change to this output -Change of autocombinedust goes to the adress being combined instead of a change address
1 parent 10426c7 commit 3f9e746

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

src/wallet.cpp

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2713,11 +2713,25 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
27132713
// TODO: pass in scriptChange instead of reservekey so
27142714
// change transaction isn't always pay-to-pivx-address
27152715
CScript scriptChange;
2716+
bool combineChange = false;
27162717

27172718
// coin control: send change to custom address
2718-
if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
2719+
if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange)) {
27192720
scriptChange = GetScriptForDestination(coinControl->destChange);
27202721

2722+
vector<CTxOut>::iterator it = txNew.vout.begin();
2723+
for (; it != txNew.vout.end();) {
2724+
if (scriptChange == it->scriptPubKey) {
2725+
it->nValue += nChange;
2726+
nChange = 0;
2727+
reservekey.ReturnKey();
2728+
combineChange = true;
2729+
break;
2730+
}
2731+
++it;
2732+
}
2733+
}
2734+
27212735
// no coin control: send change to newly generated address
27222736
else {
27232737
// Note: We use a new key here to keep it from being obvious which side is the change.
@@ -2736,18 +2750,20 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
27362750
scriptChange = GetScriptForDestination(vchPubKey.GetID());
27372751
}
27382752

2739-
CTxOut newTxOut(nChange, scriptChange);
2740-
2741-
// Never create dust outputs; if we would, just
2742-
// add the dust to the fee.
2743-
if (newTxOut.IsDust(::minRelayTxFee)) {
2744-
nFeeRet += nChange;
2745-
nChange = 0;
2746-
reservekey.ReturnKey();
2747-
} else {
2748-
// Insert change txn at random position:
2749-
vector<CTxOut>::iterator position = txNew.vout.begin() + GetRandInt(txNew.vout.size() + 1);
2750-
txNew.vout.insert(position, newTxOut);
2753+
if (!combineChange) {
2754+
CTxOut newTxOut(nChange, scriptChange);
2755+
2756+
// Never create dust outputs; if we would, just
2757+
// add the dust to the fee.
2758+
if (newTxOut.IsDust(::minRelayTxFee)) {
2759+
nFeeRet += nChange;
2760+
nChange = 0;
2761+
reservekey.ReturnKey();
2762+
} else {
2763+
// Insert change txn at random position:
2764+
vector<CTxOut>::iterator position = txNew.vout.begin() + GetRandInt(txNew.vout.size() + 1);
2765+
txNew.vout.insert(position, newTxOut);
2766+
}
27512767
}
27522768
} else
27532769
reservekey.ReturnKey();
@@ -4036,6 +4052,14 @@ void CWallet::AutoCombineDust()
40364052
CScript scriptPubKey = GetScriptForDestination(it->first.Get());
40374053
vecSend.push_back(make_pair(scriptPubKey, nTotalRewardsValue));
40384054

4055+
//Send change to same address
4056+
CTxDestination destMyAddress;
4057+
if (!ExtractDestination(scriptPubKey, destMyAddress)) {
4058+
LogPrintf("AutoCombineDust: failed to extract destination\n");
4059+
continue;
4060+
}
4061+
coinControl->destChange = destMyAddress;
4062+
40394063
// Create the transaction and commit it to the network
40404064
CWalletTx wtx;
40414065
CReserveKey keyChange(this); // this change address does not end up being used, because change is returned with coin control switch

0 commit comments

Comments
 (0)