/ src / wallet / coincontrol.h
coincontrol.h
  1  // Copyright (c) 2011-2022 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_COINCONTROL_H
  6  #define BITCOIN_WALLET_COINCONTROL_H
  7  
  8  #include <outputtype.h>
  9  #include <policy/feerate.h>
 10  #include <policy/fees.h>
 11  #include <primitives/transaction.h>
 12  #include <script/keyorigin.h>
 13  #include <script/signingprovider.h>
 14  
 15  #include <algorithm>
 16  #include <map>
 17  #include <optional>
 18  #include <set>
 19  
 20  namespace wallet {
 21  const int DEFAULT_MIN_DEPTH = 0;
 22  const int DEFAULT_MAX_DEPTH = 9999999;
 23  
 24  //! Default for -avoidpartialspends
 25  static constexpr bool DEFAULT_AVOIDPARTIALSPENDS = false;
 26  
 27  class PreselectedInput
 28  {
 29  private:
 30      //! The previous output being spent by this input
 31      std::optional<CTxOut> m_txout;
 32      //! The input weight for spending this input
 33      std::optional<int64_t> m_weight;
 34      //! The sequence number for this input
 35      std::optional<uint32_t> m_sequence;
 36      //! The scriptSig for this input
 37      std::optional<CScript> m_script_sig;
 38      //! The scriptWitness for this input
 39      std::optional<CScriptWitness> m_script_witness;
 40      //! The position in the inputs vector for this input
 41      std::optional<unsigned int> m_pos;
 42  
 43  public:
 44      /**
 45       * Set the previous output for this input.
 46       * Only necessary if the input is expected to be an external input.
 47       */
 48      void SetTxOut(const CTxOut& txout);
 49      /** Retrieve the previous output for this input. */
 50      CTxOut GetTxOut() const;
 51      /** Return whether the previous output is set for this input. */
 52      bool HasTxOut() const;
 53  
 54      /** Set the weight for this input. */
 55      void SetInputWeight(int64_t weight);
 56      /** Retrieve the input weight for this input. */
 57      std::optional<int64_t> GetInputWeight() const;
 58  
 59      /** Set the sequence for this input. */
 60      void SetSequence(uint32_t sequence);
 61      /** Retrieve the sequence for this input. */
 62      std::optional<uint32_t> GetSequence() const;
 63  
 64      /** Set the scriptSig for this input. */
 65      void SetScriptSig(const CScript& script);
 66      /** Set the scriptWitness for this input. */
 67      void SetScriptWitness(const CScriptWitness& script_wit);
 68      /** Return whether either the scriptSig or scriptWitness are set for this input. */
 69      bool HasScripts() const;
 70      /** Retrieve both the scriptSig and the scriptWitness. */
 71      std::pair<std::optional<CScript>, std::optional<CScriptWitness>> GetScripts() const;
 72  
 73      /** Store the position of this input. */
 74      void SetPosition(unsigned int pos);
 75      /** Retrieve the position of this input. */
 76      std::optional<unsigned int> GetPosition() const;
 77  };
 78  
 79  /** Coin Control Features. */
 80  class CCoinControl
 81  {
 82  public:
 83      //! Custom change destination, if not set an address is generated
 84      CTxDestination destChange = CNoDestination();
 85      //! Override the default change type if set, ignored if destChange is set
 86      std::optional<OutputType> m_change_type;
 87      //! If false, only safe inputs will be used
 88      bool m_include_unsafe_inputs = false;
 89      //! If true, the selection process can add extra unselected inputs from the wallet
 90      //! while requires all selected inputs be used
 91      bool m_allow_other_inputs = true;
 92      //! Includes watch only addresses which are solvable
 93      bool fAllowWatchOnly = false;
 94      //! Override automatic min/max checks on fee, m_feerate must be set if true
 95      bool fOverrideFeeRate = false;
 96      //! Override the wallet's m_pay_tx_fee if set
 97      std::optional<CFeeRate> m_feerate;
 98      //! Override the default confirmation target if set
 99      std::optional<unsigned int> m_confirm_target;
100      //! Override the wallet's m_signal_rbf if set
101      std::optional<bool> m_signal_bip125_rbf;
102      //! Avoid partial use of funds sent to a given address
103      bool m_avoid_partial_spends = DEFAULT_AVOIDPARTIALSPENDS;
104      //! Forbids inclusion of dirty (previously used) addresses
105      bool m_avoid_address_reuse = false;
106      //! Fee estimation mode to control arguments to estimateSmartFee
107      FeeEstimateMode m_fee_mode = FeeEstimateMode::UNSET;
108      //! Minimum chain depth value for coin availability
109      int m_min_depth = DEFAULT_MIN_DEPTH;
110      //! Maximum chain depth value for coin availability
111      int m_max_depth = DEFAULT_MAX_DEPTH;
112      //! SigningProvider that has pubkeys and scripts to do spend size estimation for external inputs
113      FlatSigningProvider m_external_provider;
114      //! Locktime
115      std::optional<uint32_t> m_locktime;
116      //! Version
117      std::optional<uint32_t> m_version;
118  
119      CCoinControl();
120  
121      /**
122       * Returns true if there are pre-selected inputs.
123       */
124      bool HasSelected() const;
125      /**
126       * Returns true if the given output is pre-selected.
127       */
128      bool IsSelected(const COutPoint& outpoint) const;
129      /**
130       * Returns true if the given output is selected as an external input.
131       */
132      bool IsExternalSelected(const COutPoint& outpoint) const;
133      /**
134       * Returns the external output for the given outpoint if it exists.
135       */
136      std::optional<CTxOut> GetExternalOutput(const COutPoint& outpoint) const;
137      /**
138       * Lock-in the given output for spending.
139       * The output will be included in the transaction even if it's not the most optimal choice.
140       */
141      PreselectedInput& Select(const COutPoint& outpoint);
142      /**
143       * Unselects the given output.
144       */
145      void UnSelect(const COutPoint& outpoint);
146      /**
147       * Unselects all outputs.
148       */
149      void UnSelectAll();
150      /**
151       * List the selected inputs.
152       */
153      std::vector<COutPoint> ListSelected() const;
154      /**
155       * Set an input's weight.
156       */
157      void SetInputWeight(const COutPoint& outpoint, int64_t weight);
158      /**
159       * Returns the input weight.
160       */
161      std::optional<int64_t> GetInputWeight(const COutPoint& outpoint) const;
162      /** Retrieve the sequence for an input */
163      std::optional<uint32_t> GetSequence(const COutPoint& outpoint) const;
164      /** Retrieves the scriptSig and scriptWitness for an input. */
165      std::pair<std::optional<CScript>, std::optional<CScriptWitness>> GetScripts(const COutPoint& outpoint) const;
166  
167      bool HasSelectedOrder() const
168      {
169          return m_selection_pos > 0;
170      }
171  
172      std::optional<unsigned int> GetSelectionPos(const COutPoint& outpoint) const
173      {
174          const auto it = m_selected.find(outpoint);
175          if (it == m_selected.end()) {
176              return std::nullopt;
177          }
178          return it->second.GetPosition();
179      }
180  
181  private:
182      //! Selected inputs (inputs that will be used, regardless of whether they're optimal or not)
183      std::map<COutPoint, PreselectedInput> m_selected;
184      unsigned int m_selection_pos{0};
185  };
186  } // namespace wallet
187  
188  #endif // BITCOIN_WALLET_COINCONTROL_H