Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 2,768 Lines • ▼ Show 20 Lines | bool CWallet::FundTransaction(CMutableTransaction &tx, Amount &nFeeRet, | ||||
} | } | ||||
// Acquire the locks to prevent races to the new locked unspents between the | // Acquire the locks to prevent races to the new locked unspents between the | ||||
// CreateTransaction call and LockCoin calls (when lockUnspents is true). | // CreateTransaction call and LockCoin calls (when lockUnspents is true). | ||||
auto locked_chain = chain().lock(); | auto locked_chain = chain().lock(); | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
CTransactionRef tx_new; | CTransactionRef tx_new; | ||||
if (!CreateTransaction(*locked_chain, vecSend, tx_new, nFeeRet, | if (!CreateTransaction(vecSend, tx_new, nFeeRet, nChangePosInOut, error, | ||||
nChangePosInOut, error, coinControl, false)) { | coinControl, false)) { | ||||
return false; | return false; | ||||
} | } | ||||
if (nChangePosInOut != -1) { | if (nChangePosInOut != -1) { | ||||
tx.vout.insert(tx.vout.begin() + nChangePosInOut, | tx.vout.insert(tx.vout.begin() + nChangePosInOut, | ||||
tx_new->vout[nChangePosInOut]); | tx_new->vout[nChangePosInOut]); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | CWallet::TransactionChangeType(OutputType change_type, | ||||
if (m_default_address_type == OutputType::LEGACY) { | if (m_default_address_type == OutputType::LEGACY) { | ||||
return OutputType::LEGACY; | return OutputType::LEGACY; | ||||
} | } | ||||
// else use m_default_address_type for change | // else use m_default_address_type for change | ||||
return m_default_address_type; | return m_default_address_type; | ||||
} | } | ||||
bool CWallet::CreateTransactionInternal(interfaces::Chain::Lock &locked_chainIn, | bool CWallet::CreateTransactionInternal(const std::vector<CRecipient> &vecSend, | ||||
const std::vector<CRecipient> &vecSend, | |||||
CTransactionRef &tx, Amount &nFeeRet, | CTransactionRef &tx, Amount &nFeeRet, | ||||
int &nChangePosInOut, | int &nChangePosInOut, | ||||
bilingual_str &error, | bilingual_str &error, | ||||
const CCoinControl &coin_control, | const CCoinControl &coin_control, | ||||
bool sign) { | bool sign) { | ||||
Amount nValue = Amount::zero(); | Amount nValue = Amount::zero(); | ||||
const OutputType change_type = TransactionChangeType( | const OutputType change_type = TransactionChangeType( | ||||
coin_control.m_change_type ? *coin_control.m_change_type | coin_control.m_change_type ? *coin_control.m_change_type | ||||
▲ Show 20 Lines • Show All 356 Lines • ▼ Show 20 Lines | bool CWallet::CreateTransactionInternal(const std::vector<CRecipient> &vecSend, | ||||
// Before we return success, we assume any change key will be used to | // Before we return success, we assume any change key will be used to | ||||
// prevent accidental re-use. | // prevent accidental re-use. | ||||
reservedest.KeepDestination(); | reservedest.KeepDestination(); | ||||
return true; | return true; | ||||
} | } | ||||
bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chain, | bool CWallet::CreateTransaction(const std::vector<CRecipient> &vecSend, | ||||
const std::vector<CRecipient> &vecSend, | |||||
CTransactionRef &tx, Amount &nFeeRet, | CTransactionRef &tx, Amount &nFeeRet, | ||||
int &nChangePosInOut, bilingual_str &error, | int &nChangePosInOut, bilingual_str &error, | ||||
const CCoinControl &coin_control, bool sign) { | const CCoinControl &coin_control, bool sign) { | ||||
int nChangePosIn = nChangePosInOut; | int nChangePosIn = nChangePosInOut; | ||||
CTransactionRef tx2 = tx; | CTransactionRef tx2 = tx; | ||||
bool res = | bool res = CreateTransactionInternal(vecSend, tx, nFeeRet, nChangePosInOut, | ||||
CreateTransactionInternal(locked_chain, vecSend, tx, nFeeRet, | error, coin_control, sign); | ||||
nChangePosInOut, error, coin_control, sign); | |||||
// try with avoidpartialspends unless it's enabled already | // try with avoidpartialspends unless it's enabled already | ||||
if (res && | if (res && | ||||
nFeeRet > | nFeeRet > | ||||
Amount::zero() /* 0 means non-functional fee rate estimation */ | Amount::zero() /* 0 means non-functional fee rate estimation */ | ||||
&& m_max_aps_fee > (-1 * SATOSHI) && | && m_max_aps_fee > (-1 * SATOSHI) && | ||||
!coin_control.m_avoid_partial_spends) { | !coin_control.m_avoid_partial_spends) { | ||||
CCoinControl tmp_cc = coin_control; | CCoinControl tmp_cc = coin_control; | ||||
tmp_cc.m_avoid_partial_spends = true; | tmp_cc.m_avoid_partial_spends = true; | ||||
Amount nFeeRet2; | Amount nFeeRet2; | ||||
int nChangePosInOut2 = nChangePosIn; | int nChangePosInOut2 = nChangePosIn; | ||||
// fired and forgotten; if an error occurs, we discard the results | // fired and forgotten; if an error occurs, we discard the results | ||||
bilingual_str error2; | bilingual_str error2; | ||||
if (CreateTransactionInternal(locked_chain, vecSend, tx2, nFeeRet2, | if (CreateTransactionInternal(vecSend, tx2, nFeeRet2, nChangePosInOut2, | ||||
nChangePosInOut2, error2, tmp_cc, sign)) { | error2, tmp_cc, sign)) { | ||||
// if fee of this alternative one is within the range of the max | // if fee of this alternative one is within the range of the max | ||||
// fee, we use this one | // fee, we use this one | ||||
const bool use_aps = nFeeRet2 <= nFeeRet + m_max_aps_fee; | const bool use_aps = nFeeRet2 <= nFeeRet + m_max_aps_fee; | ||||
WalletLogPrintf( | WalletLogPrintf( | ||||
"Fee non-grouped = %lld, grouped = %lld, using %s\n", nFeeRet, | "Fee non-grouped = %lld, grouped = %lld, using %s\n", nFeeRet, | ||||
nFeeRet2, use_aps ? "grouped" : "non-grouped"); | nFeeRet2, use_aps ? "grouped" : "non-grouped"); | ||||
if (use_aps) { | if (use_aps) { | ||||
tx = tx2; | tx = tx2; | ||||
▲ Show 20 Lines • Show All 1,013 Lines • ▼ Show 20 Lines | if (!gArgs.GetBoolArg("-rescan", false)) { | ||||
if (batch.ReadBestBlock(locator)) { | if (batch.ReadBestBlock(locator)) { | ||||
if (const Optional<int> fork_height = | if (const Optional<int> fork_height = | ||||
locked_chain->findLocatorFork(locator)) { | locked_chain->findLocatorFork(locator)) { | ||||
rescan_height = *fork_height; | rescan_height = *fork_height; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
const Optional<int> tip_height = locked_chain->getHeight(); | const Optional<int> tip_height = chain.getHeight(); | ||||
if (tip_height) { | if (tip_height) { | ||||
walletInstance->m_last_block_processed = | walletInstance->m_last_block_processed = | ||||
locked_chain->getBlockHash(*tip_height); | locked_chain->getBlockHash(*tip_height); | ||||
walletInstance->m_last_block_processed_height = *tip_height; | walletInstance->m_last_block_processed_height = *tip_height; | ||||
} else { | } else { | ||||
walletInstance->m_last_block_processed.SetNull(); | walletInstance->m_last_block_processed.SetNull(); | ||||
walletInstance->m_last_block_processed_height = -1; | walletInstance->m_last_block_processed_height = -1; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 447 Lines • Show Last 20 Lines |