diff --git a/README.md b/README.md index 1b84a23ca..6d8e3e03c 100644 --- a/README.md +++ b/README.md @@ -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 pull from Transifex would automatically overwrite them again. -To run the pre compiled binary version of flo wallet -run $bin/flo-qt +For the pre-compiled binary version of FLO, check bin/ + diff --git a/bin/README b/bin/README new file mode 100644 index 000000000..697c94701 --- /dev/null +++ b/bin/README @@ -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 diff --git a/bin/flo-cli b/bin/flo-cli new file mode 100755 index 000000000..8aadf95f5 Binary files /dev/null and b/bin/flo-cli differ diff --git a/bin/flo-tx b/bin/flo-tx new file mode 100755 index 000000000..e0904b7e5 Binary files /dev/null and b/bin/flo-tx differ diff --git a/bin/flod b/bin/flod new file mode 100755 index 000000000..83348c3b0 Binary files /dev/null and b/bin/flod differ diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index bdffcd86a..25c4c8451 100755 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2456,7 +2456,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMin return true; } -bool CWallet::SelectCoins(const std::vector& vAvailableCoins, const CAmount& nTargetValue, std::set& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const +bool CWallet::SelectCoins(const std::vector& vAvailableCoins, const CAmount& nTargetValue, std::set& setCoinsRet, CAmount& nValueRet, CTxDestination& destChange, const CCoinControl* coinControl) const { std::vector vCoins(vAvailableCoins); @@ -2488,7 +2488,27 @@ bool CWallet::SelectCoins(const std::vector& vAvailableCoins, const CAm nValueRet += out.tx->tx->vout[out.i].nValue; 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 @@ -2548,8 +2568,11 @@ bool CWallet::SelectCoins(const std::vector& vAvailableCoins, const CAm nValueRet += coin.txout.nValue; //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; + } } @@ -2571,10 +2594,20 @@ bool CWallet::SelectCoins(const std::vector& vAvailableCoins, const CAm // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end()); - // add preset inputs to the total value selected 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; } } @@ -2819,11 +2852,13 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT } txNew.vout.push_back(txout); } + + CTxDestination destChange; // Choose coins to use if (pick_new_inputs) { nValueIn = 0; setCoins.clear(); - if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, &coin_control)) + if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, destChange, &coin_control)) { strFailReason = _("Insufficient funds"); return false; @@ -2831,20 +2866,9 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT } // Send Change Back to Same (sending) Address if(!coinControlDestChange && gArgs.GetBoolArg("-SendChangeToBack", false)){ - CTxDestination destChange; - CAmount maxVal=0; - bool avail = false; - 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); - } + 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; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 9b049345c..ea89b5616 100755 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -664,7 +664,7 @@ private: * all coins from coinControl are selected; Never select unconfirmed coins * if they are not ours */ - bool SelectCoins(const std::vector& vAvailableCoins, const CAmount& nTargetValue, std::set& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = nullptr) const; + bool SelectCoins(const std::vector& vAvailableCoins, const CAmount& nTargetValue, std::set& setCoinsRet, CAmount& nValueRet, CTxDestination& destChange, const CCoinControl *coinControl = nullptr) const; CWalletDB *pwalletdbEncryption;