Line data Source code
1 : // Copyright (c) 2021 The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #ifndef BITCOIN_WALLET_SPEND_H
6 : #define BITCOIN_WALLET_SPEND_H
7 :
8 : #include <policy/fees.h> // for FeeCalculation
9 : #include <util/result.h>
10 : #include <wallet/coincontrol.h>
11 : #include <wallet/coinselection.h>
12 : #include <wallet/transaction.h>
13 : #include <wallet/wallet.h>
14 :
15 : #include <optional>
16 :
17 : namespace wallet {
18 : //! Special value for setting a random position for change output
19 : constexpr int RANDOM_CHANGE_POSITION{-1};
20 :
21 : /** Get the marginal bytes if spending the specified output from this transaction.
22 : * Use CoinControl to determine whether to expect signature grinding when calculating the size of the input spend. */
23 : int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet, const CCoinControl* coin_control = nullptr);
24 : int CalculateMaximumSignedInputSize(const CTxOut& txout, const COutPoint outpoint, const SigningProvider* pwallet, const CCoinControl* coin_control = nullptr);
25 :
26 : /** Calculate the size of the transaction using CoinControl to determine
27 : * whether to expect signature grinding when calculating the size of the input spend. */
28 : int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const CCoinControl* coin_control = nullptr) EXCLUSIVE_LOCKS_REQUIRED(wallet->cs_wallet);
29 : int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, const CCoinControl* coin_control = nullptr);
30 :
31 : /**
32 : * COutputs available for spending, stored by OutputType.
33 : * This struct is really just a wrapper around OutputType vectors with a convenient
34 : * method for concatenating and returning all COutputs as one vector.
35 : *
36 : * clear(), size() methods are implemented so that one can interact with
37 : * the CoinsResult struct as if it was a vector
38 : */
39 347 : struct CoinsResult {
40 : /** Vectors for each OutputType */
41 : std::vector<COutput> legacy;
42 :
43 : /** Other is a catch-all for anything that doesn't match the known OutputTypes */
44 : std::vector<COutput> other;
45 :
46 : /** Concatenate and return all COutputs as one vector */
47 : std::vector<COutput> all() const;
48 :
49 : /** The following methods are provided so that CoinsResult can mimic a vector,
50 : * i.e., methods can work with individual OutputType vectors or on the entire object */
51 : uint64_t size() const;
52 : void clear();
53 :
54 : /** Sum of all available coins */
55 347 : CAmount total_amount{0};
56 : };
57 :
58 : /**
59 : * Populate the CoinsResult struct with vectors of available COutputs, organized by OutputType.
60 : */
61 : CoinsResult AvailableCoins(const CWallet& wallet,
62 : const CCoinControl* coinControl = nullptr,
63 : std::optional<CFeeRate> feerate = std::nullopt,
64 : const CAmount& nMinimumAmount = 1,
65 : const CAmount& nMaximumAmount = MAX_MONEY,
66 : const CAmount& nMinimumSumAmount = MAX_MONEY,
67 : const uint64_t nMaximumCount = 0,
68 : bool only_spendable = true) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
69 :
70 : /**
71 : * Wrapper function for AvailableCoins which skips the `feerate` parameter. Use this function
72 : * to list all available coins (e.g. listunspent RPC) while not intending to fund a transaction.
73 : */
74 : 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) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
75 :
76 : CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl = nullptr);
77 :
78 : /**
79 : * Find non-change parent output.
80 : */
81 : const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const CTransaction& tx, int output) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
82 : const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const COutPoint& outpoint) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
83 :
84 : /**
85 : * Return list of available coins and locked coins grouped by non-change output address.
86 : */
87 : std::map<CTxDestination, std::vector<COutput>> ListCoins(const CWallet& wallet) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
88 :
89 : std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<COutput>& outputs, const CoinSelectionParams& coin_sel_params, const CoinEligibilityFilter& filter, bool positive_only);
90 :
91 : /**
92 : * Attempt to find a valid input set that preserves privacy by not mixing OutputTypes.
93 : * `ChooseSelectionResult()` will be called on each OutputType individually and the best
94 : * the solution (according to the waste metric) will be chosen. If a valid input cannot be found from any
95 : * single OutputType, fallback to running `ChooseSelectionResult()` over all available coins.
96 : *
97 : * param@[in] wallet The wallet which provides solving data for the coins
98 : * param@[in] nTargetValue The target value
99 : * param@[in] eligibility_filter A filter containing rules for which coins are allowed to be included in this selection
100 : * param@[in] available_coins The struct of coins, organized by OutputType, available for selection prior to filtering
101 : * param@[in] coin_selection_params Parameters for the coin selection
102 : * param@[in] allow_mixed_output_types Relax restriction that SelectionResults must be of the same OutputType
103 : * returns If successful, a SelectionResult containing the input set
104 : * If failed, a nullopt
105 : */
106 : std::optional<SelectionResult> AttemptSelection(const CWallet& wallet, const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, const CoinsResult& available_coins,
107 : const CoinSelectionParams& coin_selection_params, bool allow_mixed_output_types, CoinType nCoinType = CoinType::ALL_COINS);
108 :
109 : /**
110 : * Attempt to find a valid input set that meets the provided eligibility filter and target.
111 : * Multiple coin selection algorithms will be run and the input set that produces the least waste
112 : * (according to the waste metric) will be chosen.
113 : *
114 : * param@[in] wallet The wallet which provides solving data for the coins
115 : * param@[in] nTargetValue The target value
116 : * param@[in] eligilibity_filter A filter containing rules for which coins are allowed to be included in this selection
117 : * param@[in] available_coins The struct of coins, organized by OutputType, available for selection prior to filtering
118 : * param@[in] coin_selection_params Parameters for the coin selection
119 : * returns If successful, a SelectionResult containing the input set
120 : * If failed, a nullopt
121 : */
122 : std::optional<SelectionResult> ChooseSelectionResult(const CWallet& wallet, const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, const std::vector<COutput>& available_coins,
123 : const CoinSelectionParams& coin_selection_params, CoinType nCoinType = CoinType::ALL_COINS);
124 :
125 : /**
126 : * Select a set of coins such that nTargetValue is met and at least
127 : * all coins from coin_control are selected; never select unconfirmed coins if they are not ours
128 : * param@[in] wallet The wallet which provides data necessary to spend the selected coins
129 : * param@[in] available_coins The struct of coins, organized by OutputType, available for selection prior to filtering
130 : * param@[in] nTargetValue The target value
131 : * param@[in] coin_selection_params Parameters for this coin selection such as feerates, whether to avoid partial spends,
132 : * and whether to subtract the fee from the outputs.
133 : * returns If successful, a SelectionResult containing the selected coins
134 : * If failed, a nullopt.
135 : */
136 : std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& available_coins, const CAmount& nTargetValue, const CCoinControl& coin_control,
137 : const CoinSelectionParams& coin_selection_params) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
138 :
139 : struct CreatedTransactionResult
140 : {
141 : CTransactionRef tx;
142 : CAmount fee;
143 : FeeCalculation fee_calc;
144 : int change_pos;
145 :
146 312 : CreatedTransactionResult(CTransactionRef _tx, CAmount _fee, int _change_pos, const FeeCalculation& _fee_calc)
147 312 : : tx(_tx), fee(_fee), fee_calc(_fee_calc), change_pos(_change_pos) {}
148 : };
149 :
150 : /**
151 : * Create a new transaction paying the recipients with a set of coins
152 : * selected by SelectCoins(); Also create the change output, when needed
153 : * @note passing change_pos as -1 will result in setting a random position
154 : */
155 : util::Result<CreatedTransactionResult> CreateTransaction(CWallet& wallet, const std::vector<CRecipient>& vecSend, int change_pos, const CCoinControl& coin_control, bool sign = true, int nExtraPayloadSize = 0);
156 :
157 : /**
158 : * Insert additional inputs into the transaction by
159 : * calling CreateTransaction();
160 : */
161 : bool FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, bilingual_str& error, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl);
162 :
163 : bool GenBudgetSystemCollateralTx(CWallet& wallet, CTransactionRef& tx, uint256 hash, CAmount amount, const COutPoint& outpoint = COutPoint());
164 : } // namespace wallet
165 :
166 : #endif // BITCOIN_WALLET_SPEND_H
|