Initial merge
This commit is contained in:
@@ -824,13 +824,11 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||
return false;
|
||||
|
||||
CKeyingMaterial vMasterKey;
|
||||
RandAddSeedPerfmon();
|
||||
|
||||
vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
|
||||
GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
|
||||
|
||||
CMasterKey kMasterKey;
|
||||
RandAddSeedPerfmon();
|
||||
|
||||
kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
|
||||
GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
|
||||
@@ -1285,12 +1283,7 @@ mapNoteData_t CWallet::FindMyNotes(const CTransaction& tx) const
|
||||
noteData.insert(std::make_pair(jsoutpt, nd));
|
||||
}
|
||||
break;
|
||||
} catch (const std::runtime_error &err) {
|
||||
if (memcmp("Could not decrypt message", err.what(), 25) != 0) {
|
||||
// Unexpected failure
|
||||
LogPrintf("FindMyNotes(): Unexpected runtime error while testing decrypt:\n");
|
||||
LogPrintf("%s\n", err.what());
|
||||
} // else
|
||||
} catch (const note_decryption_failed &err) {
|
||||
// Couldn't decrypt with this decryptor
|
||||
} catch (const std::exception &exc) {
|
||||
// Unexpected failure
|
||||
@@ -2463,7 +2456,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int
|
||||
bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, bool& fOnlyCoinbaseCoinsRet, bool& fNeedCoinbaseCoinsRet, const CCoinControl* coinControl,uint64_t *interestp) const
|
||||
{
|
||||
// Output parameter fOnlyCoinbaseCoinsRet is set to true when the only available coins are coinbase utxos.
|
||||
uint64_t tmp,interest = 0;
|
||||
uint64_t tmp,interest = 0; int32_t retval;
|
||||
if ( interestp == 0 )
|
||||
{
|
||||
interestp = &tmp;
|
||||
@@ -2502,13 +2495,13 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*
|
||||
fNeedCoinbaseCoinsRet = (valueWithCoinbase >= nTargetValue);
|
||||
}
|
||||
}
|
||||
// coin control -> return all selected outputs (we want all to go into the transaction for sure)
|
||||
if (coinControl && coinControl->HasSelected())
|
||||
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
|
||||
if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
|
||||
{
|
||||
BOOST_FOREACH(const COutput& out, vCoins)
|
||||
{
|
||||
if(!out.fSpendable)
|
||||
continue;
|
||||
if (!out.fSpendable)
|
||||
continue;
|
||||
nValueRet += out.tx->vout[out.i].nValue;
|
||||
if ( KOMODO_EXCHANGEWALLET == 0 )
|
||||
*interestp += out.tx->vout[out.i].interest;
|
||||
@@ -2516,30 +2509,119 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*
|
||||
}
|
||||
return (nValueRet >= nTargetValue);
|
||||
}
|
||||
//fprintf(stderr,"nValueRet %8f vs target %.8f\n",(double)nValueRet/COIN,(double)nTargetValue/COIN);
|
||||
if ( SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet,&interest) != 0 )
|
||||
// calculate value from preset inputs and store them
|
||||
set<pair<const CWalletTx*, uint32_t> > setPresetCoins;
|
||||
CAmount nValueFromPresetInputs = 0;
|
||||
|
||||
std::vector<COutPoint> vPresetInputs;
|
||||
if (coinControl)
|
||||
coinControl->ListSelected(vPresetInputs);
|
||||
BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs)
|
||||
{
|
||||
map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
|
||||
if (it != mapWallet.end())
|
||||
{
|
||||
const CWalletTx* pcoin = &it->second;
|
||||
// Clearly invalid input, fail
|
||||
if (pcoin->vout.size() <= outpoint.n)
|
||||
return false;
|
||||
nValueFromPresetInputs += pcoin->vout[outpoint.n].nValue;
|
||||
if ( KOMODO_EXCHANGEWALLET == 0 )
|
||||
nValueFromPresetInputs += pcoin->vout[outpoint.n].interest;
|
||||
setPresetCoins.insert(make_pair(pcoin, outpoint.n));
|
||||
} else
|
||||
return false; // TODO: Allow non-wallet inputs
|
||||
}
|
||||
|
||||
// remove preset inputs from vCoins
|
||||
for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
|
||||
{
|
||||
if (setPresetCoins.count(make_pair(it->tx, it->i)))
|
||||
it = vCoins.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
retval = false;
|
||||
if ( nTargetValue <= nValueFromPresetInputs )
|
||||
retval = true;
|
||||
else if ( SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet,&interest) != 0 )
|
||||
{
|
||||
*interestp += interest;
|
||||
return(true);
|
||||
retval = true;
|
||||
}
|
||||
else if ( SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet,&interest) != 0 )
|
||||
{
|
||||
*interestp += interest;
|
||||
return(true);
|
||||
retval = true;
|
||||
}
|
||||
else if ( bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet,&interest) != 0 )
|
||||
{
|
||||
*interestp += interest;
|
||||
return(true);
|
||||
retval = true;
|
||||
}
|
||||
return(false);
|
||||
|
||||
//return (SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet,interestp) ||
|
||||
// SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet,interestp) ||
|
||||
// (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet,interestp)));
|
||||
/*bool res = nTargetValue <= nValueFromPresetInputs ||
|
||||
SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, vCoins, setCoinsRet, nValueRet) ||
|
||||
SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, vCoins, setCoinsRet, nValueRet) ||
|
||||
(bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, vCoins, setCoinsRet, nValueRet));*/
|
||||
|
||||
// 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;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend,
|
||||
CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl)
|
||||
bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason)
|
||||
{
|
||||
vector<CRecipient> vecSend;
|
||||
|
||||
// Turn the txout set into a CRecipient vector
|
||||
BOOST_FOREACH(const CTxOut& txOut, tx.vout)
|
||||
{
|
||||
CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, false};
|
||||
vecSend.push_back(recipient);
|
||||
}
|
||||
|
||||
CCoinControl coinControl;
|
||||
coinControl.fAllowOtherInputs = true;
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
coinControl.Select(txin.prevout);
|
||||
|
||||
CReserveKey reservekey(this);
|
||||
CWalletTx wtx;
|
||||
if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false))
|
||||
return false;
|
||||
|
||||
if (nChangePosRet != -1)
|
||||
tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]);
|
||||
|
||||
// Add new txins (keeping original txin scriptSig/order)
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
{
|
||||
bool found = false;
|
||||
BOOST_FOREACH(const CTxIn& origTxIn, tx.vin)
|
||||
{
|
||||
if (txin.prevout.hash == origTxIn.prevout.hash && txin.prevout.n == origTxIn.prevout.n)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
tx.vin.push_back(txin);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
|
||||
int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
|
||||
{
|
||||
uint64_t interest2,interest = 0; CAmount nValue = 0; unsigned int nSubtractFeeFromAmount = 0;
|
||||
BOOST_FOREACH (const CRecipient& recipient, vecSend)
|
||||
@@ -2774,23 +2856,43 @@ fprintf(stderr,"wallet change %.8f (%.8f - %.8f) interest %.8f interest2 %.8f to
|
||||
|
||||
// Sign
|
||||
int nIn = 0;
|
||||
CTransaction txNewConst(txNew);
|
||||
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
|
||||
if (!SignSignature(*this, *coin.first, txNew, nIn++))
|
||||
{
|
||||
bool signSuccess;
|
||||
const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
|
||||
CScript& scriptSigRes = txNew.vin[nIn].scriptSig;
|
||||
if (sign)
|
||||
signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, SIGHASH_ALL), scriptPubKey, scriptSigRes);
|
||||
else
|
||||
signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, scriptSigRes);
|
||||
|
||||
if (!signSuccess)
|
||||
{
|
||||
strFailReason = _("Signing transaction failed");
|
||||
return false;
|
||||
}
|
||||
nIn++;
|
||||
}
|
||||
|
||||
unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
// Remove scriptSigs if we used dummy signatures for fee calculation
|
||||
if (!sign) {
|
||||
BOOST_FOREACH (CTxIn& vin, txNew.vin)
|
||||
vin.scriptSig = CScript();
|
||||
}
|
||||
|
||||
// Embed the constructed transaction data in wtxNew.
|
||||
*static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
|
||||
|
||||
// Limit size
|
||||
unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION);
|
||||
if (nBytes >= MAX_TX_SIZE)
|
||||
{
|
||||
strFailReason = _("Transaction too large");
|
||||
return false;
|
||||
}
|
||||
|
||||
dPriority = wtxNew.ComputePriority(dPriority, nBytes);
|
||||
|
||||
// Can we complete this as a free transaction?
|
||||
@@ -3289,7 +3391,7 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
|
||||
return ret;
|
||||
}
|
||||
|
||||
set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const
|
||||
std::set<CTxDestination> CWallet::GetAccountAddresses(const std::string& strAccount) const
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
set<CTxDestination> result;
|
||||
@@ -3699,9 +3801,12 @@ void CWallet::GetFilteredNotes(std::vector<CNotePlaintextEntry> & outEntries, st
|
||||
|
||||
outEntries.push_back(CNotePlaintextEntry{jsop, plaintext});
|
||||
|
||||
} catch (const std::exception &) {
|
||||
} catch (const note_decryption_failed &err) {
|
||||
// Couldn't decrypt with this spending key
|
||||
throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", CZCPaymentAddress(pa).ToString()));
|
||||
} catch (const std::exception &exc) {
|
||||
// Unexpected failure
|
||||
throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", CZCPaymentAddress(pa).ToString(), exc.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user