mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 22:50:59 +01:00
Merge #9262: Prefer coins that have fewer ancestors, sanity check txn before ATMP
cee1612reduce number of lookups in TransactionWithinChainLimit (Gregory Sanders)af9bedbTest for fix of txn chaining in wallet (Gregory Sanders)5882c09CreateTransaction: Don't return success with too-many-ancestor txn (Gregory Sanders)0b2294aSelectCoinsMinConf: Prefer coins with fewer ancestors (Gregory Sanders)
This commit is contained in:
@@ -2018,7 +2018,7 @@ static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,uns
|
||||
}
|
||||
}
|
||||
|
||||
bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,
|
||||
bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMine, const int nConfTheirs, const uint64_t nMaxAncestors, vector<COutput> vCoins,
|
||||
set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const
|
||||
{
|
||||
setCoinsRet.clear();
|
||||
@@ -2043,6 +2043,9 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int
|
||||
if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
|
||||
continue;
|
||||
|
||||
if (!mempool.TransactionWithinChainLimit(pcoin->GetHash(), nMaxAncestors))
|
||||
continue;
|
||||
|
||||
int i = output.i;
|
||||
CAmount n = pcoin->tx->vout[i].nValue;
|
||||
|
||||
@@ -2168,10 +2171,17 @@ bool CWallet::SelectCoins(const vector<COutput>& vAvailableCoins, const CAmount&
|
||||
++it;
|
||||
}
|
||||
|
||||
size_t nMaxChainLength = std::min(GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT), GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT));
|
||||
bool fRejectLongChains = GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS);
|
||||
|
||||
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));
|
||||
SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, 0, vCoins, setCoinsRet, nValueRet) ||
|
||||
SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, 0, vCoins, setCoinsRet, nValueRet) ||
|
||||
(bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, 2, vCoins, setCoinsRet, nValueRet)) ||
|
||||
(bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, std::min((size_t)4, nMaxChainLength/3), vCoins, setCoinsRet, nValueRet)) ||
|
||||
(bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, nMaxChainLength/2, vCoins, setCoinsRet, nValueRet)) ||
|
||||
(bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, nMaxChainLength, vCoins, setCoinsRet, nValueRet)) ||
|
||||
(bSpendZeroConfChange && !fRejectLongChains && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, std::numeric_limits<uint64_t>::max(), vCoins, setCoinsRet, nValueRet));
|
||||
|
||||
// because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
|
||||
setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
|
||||
@@ -2550,6 +2560,21 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
||||
}
|
||||
}
|
||||
|
||||
if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
|
||||
// Lastly, ensure this tx will pass the mempool's chain limits
|
||||
LockPoints lp;
|
||||
CTxMemPoolEntry entry(txNew, 0, 0, 0, 0, false, 0, false, 0, lp);
|
||||
CTxMemPool::setEntries setAncestors;
|
||||
size_t nLimitAncestors = GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
|
||||
size_t nLimitAncestorSize = GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
|
||||
size_t nLimitDescendants = GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
|
||||
size_t nLimitDescendantSize = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000;
|
||||
std::string errString;
|
||||
if (!mempool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
|
||||
strFailReason = _("Transaction has too long of a mempool chain");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3374,6 +3399,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug)
|
||||
strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE));
|
||||
strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET));
|
||||
strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB));
|
||||
strUsage += HelpMessageOpt("-walletrejectlongchains", strprintf(_("Wallet will not create transactions that violate mempool chain limits (default: %u"), DEFAULT_WALLET_REJECT_LONG_CHAINS));
|
||||
}
|
||||
|
||||
return strUsage;
|
||||
|
||||
Reference in New Issue
Block a user