coincontrol.h raw

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