mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-21 22:42:04 +01:00
wallet: group AvailableCoins filtering parameters in a single struct
Plus clean callers that use the params default values
This commit is contained in:
parent
f0f6a3577b
commit
61c2265629
5 changed files with 44 additions and 50 deletions
|
@ -111,9 +111,10 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type
|
||||||
CAmount target = 0;
|
CAmount target = 0;
|
||||||
if (preset_inputs) {
|
if (preset_inputs) {
|
||||||
// Select inputs, each has 49 BTC
|
// Select inputs, each has 49 BTC
|
||||||
|
wallet::CoinFilterParams filter_coins;
|
||||||
|
filter_coins.nMaximumCount = preset_inputs->num_of_internal_inputs;
|
||||||
const auto& res = WITH_LOCK(wallet.cs_wallet,
|
const auto& res = WITH_LOCK(wallet.cs_wallet,
|
||||||
return wallet::AvailableCoins(wallet, nullptr, std::nullopt, 1, MAX_MONEY,
|
return wallet::AvailableCoins(wallet, /*coinControl=*/nullptr, /*feerate=*/std::nullopt, filter_coins));
|
||||||
MAX_MONEY, preset_inputs->num_of_internal_inputs));
|
|
||||||
for (int i=0; i < preset_inputs->num_of_internal_inputs; i++) {
|
for (int i=0; i < preset_inputs->num_of_internal_inputs; i++) {
|
||||||
const auto& coin{res.coins.at(output_type)[i]};
|
const auto& coin{res.coins.at(output_type)[i]};
|
||||||
target += coin.txout.nValue;
|
target += coin.txout.nValue;
|
||||||
|
|
|
@ -591,11 +591,8 @@ RPCHelpMan listunspent()
|
||||||
include_unsafe = request.params[3].get_bool();
|
include_unsafe = request.params[3].get_bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
CAmount nMinimumAmount = 0;
|
CoinFilterParams filter_coins;
|
||||||
CAmount nMaximumAmount = MAX_MONEY;
|
filter_coins.nMinimumAmount = 0;
|
||||||
CAmount nMinimumSumAmount = MAX_MONEY;
|
|
||||||
uint64_t nMaximumCount = 0;
|
|
||||||
bool include_immature_coinbase{false};
|
|
||||||
|
|
||||||
if (!request.params[4].isNull()) {
|
if (!request.params[4].isNull()) {
|
||||||
const UniValue& options = request.params[4].get_obj();
|
const UniValue& options = request.params[4].get_obj();
|
||||||
|
@ -611,19 +608,19 @@ RPCHelpMan listunspent()
|
||||||
true, true);
|
true, true);
|
||||||
|
|
||||||
if (options.exists("minimumAmount"))
|
if (options.exists("minimumAmount"))
|
||||||
nMinimumAmount = AmountFromValue(options["minimumAmount"]);
|
filter_coins.nMinimumAmount = AmountFromValue(options["minimumAmount"]);
|
||||||
|
|
||||||
if (options.exists("maximumAmount"))
|
if (options.exists("maximumAmount"))
|
||||||
nMaximumAmount = AmountFromValue(options["maximumAmount"]);
|
filter_coins.nMaximumAmount = AmountFromValue(options["maximumAmount"]);
|
||||||
|
|
||||||
if (options.exists("minimumSumAmount"))
|
if (options.exists("minimumSumAmount"))
|
||||||
nMinimumSumAmount = AmountFromValue(options["minimumSumAmount"]);
|
filter_coins.nMinimumSumAmount = AmountFromValue(options["minimumSumAmount"]);
|
||||||
|
|
||||||
if (options.exists("maximumCount"))
|
if (options.exists("maximumCount"))
|
||||||
nMaximumCount = options["maximumCount"].getInt<int64_t>();
|
filter_coins.nMaximumCount = options["maximumCount"].getInt<int64_t>();
|
||||||
|
|
||||||
if (options.exists("include_immature_coinbase")) {
|
if (options.exists("include_immature_coinbase")) {
|
||||||
include_immature_coinbase = options["include_immature_coinbase"].get_bool();
|
filter_coins.include_immature_coinbase = options["include_immature_coinbase"].get_bool();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,7 +637,7 @@ RPCHelpMan listunspent()
|
||||||
cctl.m_max_depth = nMaxDepth;
|
cctl.m_max_depth = nMaxDepth;
|
||||||
cctl.m_include_unsafe_inputs = include_unsafe;
|
cctl.m_include_unsafe_inputs = include_unsafe;
|
||||||
LOCK(pwallet->cs_wallet);
|
LOCK(pwallet->cs_wallet);
|
||||||
vecOutputs = AvailableCoinsListUnspent(*pwallet, &cctl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, include_immature_coinbase).All();
|
vecOutputs = AvailableCoinsListUnspent(*pwallet, &cctl, filter_coins).All();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(pwallet->cs_wallet);
|
LOCK(pwallet->cs_wallet);
|
||||||
|
|
|
@ -1385,7 +1385,9 @@ RPCHelpMan sendall()
|
||||||
total_input_value += tx->tx->vout[input.prevout.n].nValue;
|
total_input_value += tx->tx->vout[input.prevout.n].nValue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const COutput& output : AvailableCoins(*pwallet, &coin_control, fee_rate, /*nMinimumAmount=*/0).All()) {
|
CoinFilterParams coins_params;
|
||||||
|
coins_params.nMinimumAmount = 0;
|
||||||
|
for (const COutput& output : AvailableCoins(*pwallet, &coin_control, fee_rate, coins_params).All()) {
|
||||||
CHECK_NONFATAL(output.input_bytes > 0);
|
CHECK_NONFATAL(output.input_bytes > 0);
|
||||||
if (send_max && fee_rate.GetFee(output.input_bytes) > output.txout.nValue) {
|
if (send_max && fee_rate.GetFee(output.input_bytes) > output.txout.nValue) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -191,12 +191,7 @@ util::Result<PreSelectedInputs> FetchSelectedInputs(const CWallet& wallet, const
|
||||||
CoinsResult AvailableCoins(const CWallet& wallet,
|
CoinsResult AvailableCoins(const CWallet& wallet,
|
||||||
const CCoinControl* coinControl,
|
const CCoinControl* coinControl,
|
||||||
std::optional<CFeeRate> feerate,
|
std::optional<CFeeRate> feerate,
|
||||||
const CAmount& nMinimumAmount,
|
const CoinFilterParams& params)
|
||||||
const CAmount& nMaximumAmount,
|
|
||||||
const CAmount& nMinimumSumAmount,
|
|
||||||
const uint64_t nMaximumCount,
|
|
||||||
bool only_spendable,
|
|
||||||
bool include_immature_coinbase)
|
|
||||||
{
|
{
|
||||||
AssertLockHeld(wallet.cs_wallet);
|
AssertLockHeld(wallet.cs_wallet);
|
||||||
|
|
||||||
|
@ -214,7 +209,7 @@ CoinsResult AvailableCoins(const CWallet& wallet,
|
||||||
const uint256& wtxid = entry.first;
|
const uint256& wtxid = entry.first;
|
||||||
const CWalletTx& wtx = entry.second;
|
const CWalletTx& wtx = entry.second;
|
||||||
|
|
||||||
if (wallet.IsTxImmatureCoinBase(wtx) && !include_immature_coinbase)
|
if (wallet.IsTxImmatureCoinBase(wtx) && !params.include_immature_coinbase)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int nDepth = wallet.GetTxDepthInMainChain(wtx);
|
int nDepth = wallet.GetTxDepthInMainChain(wtx);
|
||||||
|
@ -273,7 +268,7 @@ CoinsResult AvailableCoins(const CWallet& wallet,
|
||||||
const CTxOut& output = wtx.tx->vout[i];
|
const CTxOut& output = wtx.tx->vout[i];
|
||||||
const COutPoint outpoint(wtxid, i);
|
const COutPoint outpoint(wtxid, i);
|
||||||
|
|
||||||
if (output.nValue < nMinimumAmount || output.nValue > nMaximumAmount)
|
if (output.nValue < params.nMinimumAmount || output.nValue > params.nMaximumAmount)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Skip manually selected coins (the caller can fetch them directly)
|
// Skip manually selected coins (the caller can fetch them directly)
|
||||||
|
@ -305,7 +300,7 @@ CoinsResult AvailableCoins(const CWallet& wallet,
|
||||||
bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
|
bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
|
||||||
|
|
||||||
// Filter by spendable outputs only
|
// Filter by spendable outputs only
|
||||||
if (!spendable && only_spendable) continue;
|
if (!spendable && params.only_spendable) continue;
|
||||||
|
|
||||||
// Obtain script type
|
// Obtain script type
|
||||||
std::vector<std::vector<uint8_t>> script_solutions;
|
std::vector<std::vector<uint8_t>> script_solutions;
|
||||||
|
@ -329,14 +324,14 @@ CoinsResult AvailableCoins(const CWallet& wallet,
|
||||||
// Cache total amount as we go
|
// Cache total amount as we go
|
||||||
result.total_amount += output.nValue;
|
result.total_amount += output.nValue;
|
||||||
// Checks the sum amount of all UTXO's.
|
// Checks the sum amount of all UTXO's.
|
||||||
if (nMinimumSumAmount != MAX_MONEY) {
|
if (params.nMinimumSumAmount != MAX_MONEY) {
|
||||||
if (result.total_amount >= nMinimumSumAmount) {
|
if (result.total_amount >= params.nMinimumSumAmount) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks the maximum number of UTXO's.
|
// Checks the maximum number of UTXO's.
|
||||||
if (nMaximumCount > 0 && result.Size() >= nMaximumCount) {
|
if (params.nMaximumCount > 0 && result.Size() >= params.nMaximumCount) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,21 +340,16 @@ CoinsResult AvailableCoins(const CWallet& wallet,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl* coinControl, const CAmount& nMinimumAmount, const CAmount& nMaximumAmount, const CAmount& nMinimumSumAmount, const uint64_t nMaximumCount, bool include_immature_coinbase)
|
CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl* coinControl, CoinFilterParams params)
|
||||||
{
|
{
|
||||||
return AvailableCoins(wallet, coinControl, /*feerate=*/ std::nullopt, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, /*only_spendable=*/false, include_immature_coinbase);
|
params.only_spendable = false;
|
||||||
|
return AvailableCoins(wallet, coinControl, /*feerate=*/ std::nullopt, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl)
|
CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl)
|
||||||
{
|
{
|
||||||
LOCK(wallet.cs_wallet);
|
LOCK(wallet.cs_wallet);
|
||||||
return AvailableCoins(wallet, coinControl,
|
return AvailableCoins(wallet, coinControl).total_amount;
|
||||||
/*feerate=*/ std::nullopt,
|
|
||||||
/*nMinimumAmount=*/ 1,
|
|
||||||
/*nMaximumAmount=*/ MAX_MONEY,
|
|
||||||
/*nMinimumSumAmount=*/ MAX_MONEY,
|
|
||||||
/*nMaximumCount=*/ 0
|
|
||||||
).total_amount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const CTransaction& tx, int output)
|
const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const CTransaction& tx, int output)
|
||||||
|
@ -898,13 +888,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
|
||||||
// allowed (coins automatically selected by the wallet)
|
// allowed (coins automatically selected by the wallet)
|
||||||
CoinsResult available_coins;
|
CoinsResult available_coins;
|
||||||
if (coin_control.m_allow_other_inputs) {
|
if (coin_control.m_allow_other_inputs) {
|
||||||
available_coins = AvailableCoins(wallet,
|
available_coins = AvailableCoins(wallet, &coin_control, coin_selection_params.m_effective_feerate);
|
||||||
&coin_control,
|
|
||||||
coin_selection_params.m_effective_feerate,
|
|
||||||
1, /*nMinimumAmount*/
|
|
||||||
MAX_MONEY, /*nMaximumAmount*/
|
|
||||||
MAX_MONEY, /*nMinimumSumAmount*/
|
|
||||||
0); /*nMaximumCount*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose coins to use
|
// Choose coins to use
|
||||||
|
|
|
@ -55,24 +55,34 @@ struct CoinsResult {
|
||||||
CAmount total_amount{0};
|
CAmount total_amount{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CoinFilterParams {
|
||||||
|
// Outputs below the minimum amount will not get selected
|
||||||
|
CAmount nMinimumAmount{1};
|
||||||
|
// Outputs above the maximum amount will not get selected
|
||||||
|
CAmount nMaximumAmount{MAX_MONEY};
|
||||||
|
// Return outputs until the minimum sum amount is covered
|
||||||
|
CAmount nMinimumSumAmount{MAX_MONEY};
|
||||||
|
// Maximum number of outputs that can be returned
|
||||||
|
uint64_t nMaximumCount{0};
|
||||||
|
// By default, return only spendable outputs
|
||||||
|
bool only_spendable{true};
|
||||||
|
// By default, do not include immature coinbase outputs
|
||||||
|
bool include_immature_coinbase{false};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate the CoinsResult struct with vectors of available COutputs, organized by OutputType.
|
* Populate the CoinsResult struct with vectors of available COutputs, organized by OutputType.
|
||||||
*/
|
*/
|
||||||
CoinsResult AvailableCoins(const CWallet& wallet,
|
CoinsResult AvailableCoins(const CWallet& wallet,
|
||||||
const CCoinControl* coinControl = nullptr,
|
const CCoinControl* coinControl = nullptr,
|
||||||
std::optional<CFeeRate> feerate = std::nullopt,
|
std::optional<CFeeRate> feerate = std::nullopt,
|
||||||
const CAmount& nMinimumAmount = 1,
|
const CoinFilterParams& params = {}) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
||||||
const CAmount& nMaximumAmount = MAX_MONEY,
|
|
||||||
const CAmount& nMinimumSumAmount = MAX_MONEY,
|
|
||||||
const uint64_t nMaximumCount = 0,
|
|
||||||
bool only_spendable = true,
|
|
||||||
bool include_immature_coinbase = false) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper function for AvailableCoins which skips the `feerate` parameter. Use this function
|
* Wrapper function for AvailableCoins which skips the `feerate` and `CoinFilterParams::only_spendable` parameters. Use this function
|
||||||
* to list all available coins (e.g. listunspent RPC) while not intending to fund a transaction.
|
* to list all available coins (e.g. listunspent RPC) while not intending to fund a transaction.
|
||||||
*/
|
*/
|
||||||
CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl* coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0, bool include_immature_coinbase = false) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl* coinControl = nullptr, CoinFilterParams params = {}) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
||||||
|
|
||||||
CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl = nullptr);
|
CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl = nullptr);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue