Updated SendChangeToBack feature

This commit is contained in:
sairajzero 2018-08-11 04:52:11 -07:00
parent af07c526d3
commit 6e9463bf11
7 changed files with 74 additions and 22 deletions

View File

@ -73,5 +73,5 @@ Translations are periodically pulled from Transifex and merged into the git repo
**Important**: We do not accept translation changes as GitHub pull requests because the next **Important**: We do not accept translation changes as GitHub pull requests because the next
pull from Transifex would automatically overwrite them again. pull from Transifex would automatically overwrite them again.
To run the pre compiled binary version of flo wallet For the pre-compiled binary version of FLO, check bin/
run $bin/flo-qt

28
bin/README Normal file
View File

@ -0,0 +1,28 @@
These are pre-compiled binaries of stable FLO Core Wallet.
To run FLO core wallet QT :
$./flo-qt
To run FLO testnet wallet QT :
$./flo-qt -testnet
To run FLO cli commands:
$./flo-cli
To run FLO transaction commands :
$./flo-tx
To start FLO server :
$./flod
To start FLO server in daemon mode :
$./flod -daemon
Upgrade Details :
Added 2 features to the FLO wallet :
1. CoinControlFIFO - selects the coins that were received first to be spent first (First-In-First-Out).
To enable it, add CoinControlFIFO=1 in flo.conf
2. SendChangeToBack - send the change back to the coin's original address
To enable it, add SendChangeToBack=1 in flo.conf

BIN
bin/flo-cli Executable file

Binary file not shown.

BIN
bin/flo-tx Executable file

Binary file not shown.

BIN
bin/flod Executable file

Binary file not shown.

View File

@ -2456,7 +2456,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMin
return true; return true;
} }
bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, CTxDestination& destChange, const CCoinControl* coinControl) const
{ {
std::vector<COutput> vCoins(vAvailableCoins); std::vector<COutput> vCoins(vAvailableCoins);
@ -2488,7 +2488,27 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
nValueRet += out.tx->tx->vout[out.i].nValue; nValueRet += out.tx->tx->vout[out.i].nValue;
setCoinsRet.insert(CInputCoin(out.tx, out.i)); setCoinsRet.insert(CInputCoin(out.tx, out.i));
} }
return (nValueRet >= nTargetValue); // address for SendChangeToBack
CAmount maxVal=0;
for (const CInputCoin &coin : setCoinsRet){
if(coin.txout.nValue > maxVal){
ExtractDestination(coin.txout.scriptPubKey, destChange);
maxVal = coin.txout.nValue;
}
}
bool res = (nValueRet >= nTargetValue);
// address for SendChangeToBack
if(res && gArgs.GetBoolArg("-SendChangeToBack", false)){
CAmount maxVal=0;
for (const CInputCoin &coin : setCoinsRet){
if(coin.txout.nValue > maxVal){
ExtractDestination(coin.txout.scriptPubKey, destChange);
maxVal = coin.txout.nValue;
}
}
}
return res;
} }
// calculate value from preset inputs and store them in PresetCoins set // calculate value from preset inputs and store them in PresetCoins set
@ -2548,8 +2568,11 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
nValueRet += coin.txout.nValue; nValueRet += coin.txout.nValue;
//return true if coins of required amount are selected //return true if coins of required amount are selected
if (nRemainReqValue <= 0) if (nRemainReqValue <= 0){
if(gArgs.GetBoolArg("-SendChangeToBack", false))
ExtractDestination(coin.txout.scriptPubKey, destChange);
return true; return true;
}
} }
@ -2571,10 +2594,20 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
// because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end()); setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
// add preset inputs to the total value selected // add preset inputs to the total value selected
nValueRet += nValueFromPresetInputs; nValueRet += nValueFromPresetInputs;
// address for SendChangeToBack
if(res && gArgs.GetBoolArg("-SendChangeToBack", false)){
CAmount maxVal=0;
for (const CInputCoin &coin : setCoinsRet){
if(coin.txout.nValue > maxVal){
ExtractDestination(coin.txout.scriptPubKey, destChange);
maxVal = coin.txout.nValue;
}
}
}
return res; return res;
} }
} }
@ -2819,11 +2852,13 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
} }
txNew.vout.push_back(txout); txNew.vout.push_back(txout);
} }
CTxDestination destChange;
// Choose coins to use // Choose coins to use
if (pick_new_inputs) { if (pick_new_inputs) {
nValueIn = 0; nValueIn = 0;
setCoins.clear(); setCoins.clear();
if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, &coin_control)) if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, destChange, &coin_control))
{ {
strFailReason = _("Insufficient funds"); strFailReason = _("Insufficient funds");
return false; return false;
@ -2831,20 +2866,9 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
} }
// Send Change Back to Same (sending) Address // Send Change Back to Same (sending) Address
if(!coinControlDestChange && gArgs.GetBoolArg("-SendChangeToBack", false)){ if(!coinControlDestChange && gArgs.GetBoolArg("-SendChangeToBack", false)){
CTxDestination destChange; scriptChange = GetScriptForDestination(destChange);
CAmount maxVal=0; CTxOut change_prototype_txout(0, scriptChange);
bool avail = false; size_t change_prototype_size = GetSerializeSize(change_prototype_txout, SER_DISK, 0);
for (const CInputCoin &coin : setCoins ){
if(!avail || coin.txout.nValue > maxVal){
avail = (ExtractDestination(coin.txout.scriptPubKey, destChange) || avail);
maxVal = coin.txout.nValue;
}
}
if(avail){
scriptChange = GetScriptForDestination(destChange);
CTxOut change_prototype_txout(0, scriptChange);
size_t change_prototype_size = GetSerializeSize(change_prototype_txout, SER_DISK, 0);
}
} }
const CAmount nChange = nValueIn - nValueToSelect; const CAmount nChange = nValueIn - nValueToSelect;

View File

@ -664,7 +664,7 @@ private:
* all coins from coinControl are selected; Never select unconfirmed coins * all coins from coinControl are selected; Never select unconfirmed coins
* if they are not ours * if they are not ours
*/ */
bool SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = nullptr) const; bool SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, CTxDestination& destChange, const CCoinControl *coinControl = nullptr) const;
CWalletDB *pwalletdbEncryption; CWalletDB *pwalletdbEncryption;