walletmodel.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_QT_WALLETMODEL_H
   6  #define BITCOIN_QT_WALLETMODEL_H
   7  
   8  #include <key.h>
   9  
  10  #include <qt/walletmodeltransaction.h>
  11  
  12  #include <interfaces/wallet.h>
  13  #include <primitives/transaction_identifier.h>
  14  #include <support/allocators/secure.h>
  15  
  16  #include <vector>
  17  
  18  #include <QObject>
  19  
  20  enum class OutputType;
  21  
  22  class AddressTableModel;
  23  class ClientModel;
  24  class OptionsModel;
  25  class PlatformStyle;
  26  class RecentRequestsTableModel;
  27  class SendCoinsRecipient;
  28  class TransactionTableModel;
  29  class WalletModelTransaction;
  30  
  31  class CKeyID;
  32  class COutPoint;
  33  class CPubKey;
  34  class uint256;
  35  
  36  namespace interfaces {
  37  class Node;
  38  } // namespace interfaces
  39  namespace wallet {
  40  class CCoinControl;
  41  } // namespace wallet
  42  
  43  QT_BEGIN_NAMESPACE
  44  class QTimer;
  45  QT_END_NAMESPACE
  46  
  47  /** Interface to Bitcoin wallet from Qt view code. */
  48  class WalletModel : public QObject
  49  {
  50      Q_OBJECT
  51  
  52  public:
  53      explicit WalletModel(std::unique_ptr<interfaces::Wallet> wallet, ClientModel& client_model, const PlatformStyle *platformStyle, QObject *parent = nullptr);
  54      ~WalletModel();
  55  
  56      enum StatusCode // Returned by sendCoins
  57      {
  58          OK,
  59          InvalidAmount,
  60          InvalidAddress,
  61          AmountExceedsBalance,
  62          DuplicateAddress,
  63          TransactionCreationFailed, // Error returned when wallet is still locked
  64          AbsurdFee
  65      };
  66  
  67      enum EncryptionStatus
  68      {
  69          NoKeys,       // wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)
  70          Unencrypted,  // !wallet->HasEncryptionKeys()
  71          Locked,       // wallet->HasEncryptionKeys() && wallet->IsLocked()
  72          Unlocked      // wallet->HasEncryptionKeys() && !wallet->IsLocked()
  73      };
  74  
  75      OptionsModel* getOptionsModel() const;
  76      AddressTableModel* getAddressTableModel() const;
  77      TransactionTableModel* getTransactionTableModel() const;
  78      RecentRequestsTableModel* getRecentRequestsTableModel() const;
  79  
  80      EncryptionStatus getEncryptionStatus() const;
  81  
  82      // Check address for validity
  83      bool validateAddress(const QString& address) const;
  84  
  85      // Return status record for SendCoins, contains error id + information
  86      struct SendCoinsReturn
  87      {
  88          SendCoinsReturn(StatusCode _status = OK, QString _reasonCommitFailed = "")
  89              : status(_status),
  90                reasonCommitFailed(_reasonCommitFailed)
  91          {
  92          }
  93          StatusCode status;
  94          QString reasonCommitFailed;
  95      };
  96  
  97      // prepare transaction for getting txfee before sending coins
  98      SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const wallet::CCoinControl& coinControl);
  99  
 100      // Send coins to a list of recipients
 101      void sendCoins(WalletModelTransaction& transaction);
 102  
 103      // Wallet encryption
 104      bool setWalletEncrypted(const SecureString& passphrase);
 105      // Passphrase only needed when unlocking
 106      bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
 107      bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
 108  
 109      // RAII object for unlocking wallet, returned by requestUnlock()
 110      class UnlockContext
 111      {
 112      public:
 113          UnlockContext(WalletModel *wallet, bool valid, bool relock);
 114          ~UnlockContext();
 115  
 116          bool isValid() const { return valid; }
 117  
 118          // Disable unused copy/move constructors/assignments explicitly.
 119          UnlockContext(const UnlockContext&) = delete;
 120          UnlockContext(UnlockContext&&) = delete;
 121          UnlockContext& operator=(const UnlockContext&) = delete;
 122          UnlockContext& operator=(UnlockContext&&) = delete;
 123  
 124      private:
 125          WalletModel *wallet;
 126          const bool valid;
 127          const bool relock;
 128      };
 129  
 130      UnlockContext requestUnlock();
 131  
 132      bool bumpFee(Txid hash, Txid& new_hash);
 133      void displayAddress(std::string sAddress) const;
 134  
 135      static bool isWalletEnabled();
 136  
 137      interfaces::Node& node() const { return m_node; }
 138      interfaces::Wallet& wallet() const { return *m_wallet; }
 139      ClientModel& clientModel() const { return *m_client_model; }
 140      void setClientModel(ClientModel* client_model);
 141  
 142      QString getWalletName() const;
 143      QString getDisplayName() const;
 144  
 145      bool isMultiwallet() const;
 146  
 147      void refresh(bool pk_hash_only = false);
 148  
 149      uint256 getLastBlockProcessed() const;
 150  
 151      // Retrieve the cached wallet balance
 152      interfaces::WalletBalances getCachedBalance() const;
 153  
 154      // If coin control has selected outputs, searches the total amount inside the wallet.
 155      // Otherwise, uses the wallet's cached available balance.
 156      CAmount getAvailableBalance(const wallet::CCoinControl* control);
 157  
 158  private:
 159      std::unique_ptr<interfaces::Wallet> m_wallet;
 160      std::unique_ptr<interfaces::Handler> m_handler_unload;
 161      std::unique_ptr<interfaces::Handler> m_handler_status_changed;
 162      std::unique_ptr<interfaces::Handler> m_handler_address_book_changed;
 163      std::unique_ptr<interfaces::Handler> m_handler_transaction_changed;
 164      std::unique_ptr<interfaces::Handler> m_handler_show_progress;
 165      std::unique_ptr<interfaces::Handler> m_handler_can_get_addrs_changed;
 166      ClientModel* m_client_model;
 167      interfaces::Node& m_node;
 168  
 169      bool fForceCheckBalanceChanged{false};
 170  
 171      // Wallet has an options model for wallet-specific options
 172      // (transaction fee, for example)
 173      OptionsModel *optionsModel;
 174  
 175      AddressTableModel* addressTableModel{nullptr};
 176      TransactionTableModel* transactionTableModel{nullptr};
 177      RecentRequestsTableModel* recentRequestsTableModel{nullptr};
 178  
 179      // Cache some values to be able to detect changes
 180      interfaces::WalletBalances m_cached_balances;
 181      EncryptionStatus cachedEncryptionStatus{Unencrypted};
 182      QTimer* timer;
 183  
 184      // Block hash denoting when the last balance update was done.
 185      uint256 m_cached_last_update_tip{};
 186  
 187      void subscribeToCoreSignals();
 188      void unsubscribeFromCoreSignals();
 189      void checkBalanceChanged(const interfaces::WalletBalances& new_balances);
 190  
 191  Q_SIGNALS:
 192      // Signal that balance in wallet changed
 193      void balanceChanged(const interfaces::WalletBalances& balances);
 194  
 195      // Encryption status of wallet changed
 196      void encryptionStatusChanged();
 197  
 198      // Signal emitted when wallet needs to be unlocked
 199      // It is valid behaviour for listeners to keep the wallet locked after this signal;
 200      // this means that the unlocking failed or was cancelled.
 201      void requireUnlock();
 202  
 203      // Fired when a message should be reported to the user
 204      void message(const QString &title, const QString &message, unsigned int style);
 205  
 206      // Coins sent: from wallet, to recipient, in (serialized) transaction:
 207      void coinsSent(WalletModel* wallet, SendCoinsRecipient recipient, QByteArray transaction);
 208  
 209      // Show progress dialog e.g. for rescan
 210      void showProgress(const QString &title, int nProgress);
 211  
 212      // Signal that wallet is about to be removed
 213      void unload();
 214  
 215      // Notify that there are now keys in the keypool
 216      void canGetAddressesChanged();
 217  
 218      void timerTimeout();
 219  
 220  public Q_SLOTS:
 221      /* Starts a timer to periodically update the balance */
 222      void startPollBalance();
 223  
 224      /* Wallet status might have changed */
 225      void updateStatus();
 226      /* New transaction, or transaction changed status */
 227      void updateTransaction();
 228      /* New, updated or removed address book entry */
 229      void updateAddressBook(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status);
 230      /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
 231      void pollBalanceChanged();
 232  };
 233  
 234  #endif // BITCOIN_QT_WALLETMODEL_H
 235