Skip to content

Commit

Permalink
[Wallet] Combine change to output when possible & provide it in autoc…
Browse files Browse the repository at this point in the history
…ombine

-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
  • Loading branch information
Warrows committed Jan 29, 2018
1 parent 10426c7 commit 3f9e746
Showing 1 changed file with 37 additions and 13 deletions.
50 changes: 37 additions & 13 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2713,11 +2713,25 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
// TODO: pass in scriptChange instead of reservekey so
// change transaction isn't always pay-to-pivx-address
CScript scriptChange;
bool combineChange = false;

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

vector<CTxOut>::iterator it = txNew.vout.begin();
for (; it != txNew.vout.end();) {
if (scriptChange == it->scriptPubKey) {
it->nValue += nChange;
nChange = 0;
reservekey.ReturnKey();
combineChange = true;
break;
}
++it;
}
}

// no coin control: send change to newly generated address
else {
// Note: We use a new key here to keep it from being obvious which side is the change.
Expand All @@ -2736,18 +2750,20 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
scriptChange = GetScriptForDestination(vchPubKey.GetID());
}

CTxOut newTxOut(nChange, scriptChange);

// Never create dust outputs; if we would, just
// add the dust to the fee.
if (newTxOut.IsDust(::minRelayTxFee)) {
nFeeRet += nChange;
nChange = 0;
reservekey.ReturnKey();
} else {
// Insert change txn at random position:
vector<CTxOut>::iterator position = txNew.vout.begin() + GetRandInt(txNew.vout.size() + 1);
txNew.vout.insert(position, newTxOut);
if (!combineChange) {
CTxOut newTxOut(nChange, scriptChange);

// Never create dust outputs; if we would, just
// add the dust to the fee.
if (newTxOut.IsDust(::minRelayTxFee)) {
nFeeRet += nChange;
nChange = 0;
reservekey.ReturnKey();
} else {
// Insert change txn at random position:
vector<CTxOut>::iterator position = txNew.vout.begin() + GetRandInt(txNew.vout.size() + 1);
txNew.vout.insert(position, newTxOut);
}
}
} else
reservekey.ReturnKey();
Expand Down Expand Up @@ -4036,6 +4052,14 @@ void CWallet::AutoCombineDust()
CScript scriptPubKey = GetScriptForDestination(it->first.Get());
vecSend.push_back(make_pair(scriptPubKey, nTotalRewardsValue));

//Send change to same address
CTxDestination destMyAddress;
if (!ExtractDestination(scriptPubKey, destMyAddress)) {
LogPrintf("AutoCombineDust: failed to extract destination\n");
continue;
}
coinControl->destChange = destMyAddress;

// Create the transaction and commit it to the network
CWalletTx wtx;
CReserveKey keyChange(this); // this change address does not end up being used, because change is returned with coin control switch
Expand Down

0 comments on commit 3f9e746

Please sign in to comment.