rpcconsole.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_RPCCONSOLE_H
   6  #define BITCOIN_QT_RPCCONSOLE_H
   7  
   8  #include <bitcoin-build-config.h> // IWYU pragma: keep
   9  
  10  #include <qt/clientmodel.h>
  11  #include <qt/guiutil.h>
  12  #include <qt/peertablemodel.h>
  13  
  14  #include <net.h>
  15  
  16  #include <QByteArray>
  17  #include <QCompleter>
  18  #include <QMimeData>
  19  #include <QTextDocumentFragment>
  20  #include <QTextEdit>
  21  #include <QThread>
  22  #include <QWidget>
  23  
  24  class PlatformStyle;
  25  class RPCExecutor;
  26  class WalletModel;
  27  
  28  namespace interfaces {
  29      class Node;
  30  }
  31  
  32  namespace Ui {
  33      class RPCConsole;
  34  }
  35  
  36  QT_BEGIN_NAMESPACE
  37  class QDateTime;
  38  class QMenu;
  39  class QItemSelection;
  40  QT_END_NAMESPACE
  41  
  42  /** Local Bitcoin RPC console. */
  43  class RPCConsole: public QWidget
  44  {
  45      Q_OBJECT
  46  
  47  public:
  48      explicit RPCConsole(interfaces::Node& node, const PlatformStyle *platformStyle, QWidget *parent);
  49      ~RPCConsole();
  50  
  51      static bool RPCParseCommandLine(interfaces::Node* node, std::string& strResult, const std::string& strCommand, bool fExecute, std::string* pstrFilteredOut = nullptr, const QString& wallet_name = {});
  52      static bool RPCExecuteCommandLine(interfaces::Node& node, std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = nullptr, const QString& wallet_name = {}) {
  53          return RPCParseCommandLine(&node, strResult, strCommand, true, pstrFilteredOut, wallet_name);
  54      }
  55  
  56      void setClientModel(ClientModel *model = nullptr, int bestblock_height = 0, int64_t bestblock_date = 0, double verification_progress = 0.0);
  57  
  58  #ifdef ENABLE_WALLET
  59      void addWallet(WalletModel* walletModel);
  60      void removeWallet(WalletModel* walletModel);
  61  #endif // ENABLE_WALLET
  62  
  63      enum MessageClass {
  64          MC_ERROR,
  65          MC_DEBUG,
  66          CMD_REQUEST,
  67          CMD_REPLY,
  68          CMD_ERROR
  69      };
  70  
  71      enum class TabTypes {
  72          INFO,
  73          CONSOLE,
  74          GRAPH,
  75          PEERS
  76      };
  77  
  78      std::vector<TabTypes> tabs() const { return {TabTypes::INFO, TabTypes::CONSOLE, TabTypes::GRAPH, TabTypes::PEERS}; }
  79  
  80      QString tabTitle(TabTypes tab_type) const;
  81      QKeySequence tabShortcut(TabTypes tab_type) const;
  82  
  83  protected:
  84      virtual bool eventFilter(QObject* obj, QEvent *event) override;
  85      void keyPressEvent(QKeyEvent *) override;
  86      void changeEvent(QEvent* e) override;
  87  
  88  private Q_SLOTS:
  89      void on_lineEdit_returnPressed();
  90      void on_tabWidget_currentChanged(int index);
  91      /** open the debug.log from the current datadir */
  92      void on_openDebugLogfileButton_clicked();
  93      /** change the time range of the network traffic graph */
  94      void on_sldGraphRange_valueChanged(int value);
  95      /** update traffic statistics */
  96      void updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut);
  97      void resizeEvent(QResizeEvent *event) override;
  98      void showEvent(QShowEvent *event) override;
  99      void hideEvent(QHideEvent *event) override;
 100      /** Show custom context menu on Peers tab */
 101      void showPeersTableContextMenu(const QPoint& point);
 102      /** Show custom context menu on Bans tab */
 103      void showBanTableContextMenu(const QPoint& point);
 104      /** Hides ban table if no bans are present */
 105      void showOrHideBanTableIfRequired();
 106      /** clear the selected node */
 107      void clearSelectedNode();
 108      /** show detailed information on ui about selected node */
 109      void updateDetailWidget();
 110  
 111  public Q_SLOTS:
 112      void clear(bool keep_prompt = false);
 113      void fontBigger();
 114      void fontSmaller();
 115      void setFontSize(int newSize);
 116      /** Append the message to the message widget */
 117      void message(int category, const QString &msg) { message(category, msg, false); }
 118      void message(int category, const QString &message, bool html);
 119      /** Set number of connections shown in the UI */
 120      void setNumConnections(int count);
 121      /** Set network state shown in the UI */
 122      void setNetworkActive(bool networkActive);
 123      /** Set number of blocks and last block date shown in the UI */
 124      void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, SyncType synctype);
 125      /** Set size (number of transactions and memory usage) of the mempool in the UI */
 126      void setMempoolSize(long numberOfTxs, size_t dynUsage, size_t maxUsage);
 127      /** Go forward or back in history */
 128      void browseHistory(int offset);
 129      /** Scroll console view to end */
 130      void scrollToEnd();
 131      /** Disconnect a selected node on the Peers tab */
 132      void disconnectSelectedNode();
 133      /** Ban a selected node on the Peers tab */
 134      void banSelectedNode(int bantime);
 135      /** Unban a selected node on the Bans tab */
 136      void unbanSelectedNode();
 137      /** set which tab has the focus (is visible) */
 138      void setTabFocus(enum TabTypes tabType);
 139  #ifdef ENABLE_WALLET
 140      /** Set the current (ie - active) wallet */
 141      void setCurrentWallet(WalletModel* wallet_model);
 142  #endif // ENABLE_WALLET
 143  
 144  private:
 145      struct TranslatedStrings {
 146          const QString yes{tr("Yes")}, no{tr("No")}, to{tr("To")}, from{tr("From")},
 147              ban_for{tr("Ban for")}, na{tr("N/A")}, unknown{tr("Unknown")};
 148      } const ts;
 149  
 150      void startExecutor();
 151      void setTrafficGraphRange(int mins);
 152  
 153      enum ColumnWidths
 154      {
 155          ADDRESS_COLUMN_WIDTH = 200,
 156          SUBVERSION_COLUMN_WIDTH = 150,
 157          PING_COLUMN_WIDTH = 80,
 158          BANSUBNET_COLUMN_WIDTH = 200,
 159          BANTIME_COLUMN_WIDTH = 250
 160  
 161      };
 162  
 163      interfaces::Node& m_node;
 164      Ui::RPCConsole* const ui;
 165      ClientModel *clientModel = nullptr;
 166      QStringList history;
 167      int historyPtr = 0;
 168      QString cmdBeforeBrowsing;
 169      QList<NodeId> cachedNodeids;
 170      const PlatformStyle* const platformStyle;
 171      QMenu *peersTableContextMenu = nullptr;
 172      QMenu *banTableContextMenu = nullptr;
 173      int consoleFontSize = 0;
 174      QCompleter *autoCompleter = nullptr;
 175      QThread thread;
 176      RPCExecutor* m_executor{nullptr};
 177      WalletModel* m_last_wallet_model{nullptr};
 178      bool m_is_executing{false};
 179      QByteArray m_peer_widget_header_state;
 180      QByteArray m_banlist_widget_header_state;
 181  
 182      /** Update UI with latest network info from model. */
 183      void updateNetworkState();
 184  
 185      /// Format the duration between now and event as a string.
 186      QString TimeDurationField(NodeClock::time_point now, NodeClock::time_point event) const
 187      {
 188          return event > NodeClock::epoch ? GUIUtil::formatDurationStr(now - event) : tr("Never");
 189      }
 190      /// DEPRECATED: Helper for the output of a time duration field. Inputs are UNIX epoch times.
 191      QString TimeDurationField(std::chrono::seconds time_now, std::chrono::seconds time_at_event) const
 192      {
 193          return time_at_event.count() ? GUIUtil::formatDurationStr(time_now - time_at_event) : tr("Never");
 194      }
 195  
 196      void updateWindowTitle();
 197  
 198  private Q_SLOTS:
 199      void updateAlerts(const QString& warnings);
 200  };
 201  
 202  /**
 203   * A version of QTextEdit that only populates plaintext mime data from a
 204   * selection, this avoids some bad behavior in QT's HTML->Markdown conversion.
 205   */
 206  class PlainCopyTextEdit : public QTextEdit {
 207      Q_OBJECT
 208  public:
 209      using QTextEdit::QTextEdit;
 210  protected:
 211      QMimeData* createMimeDataFromSelection() const override {
 212          auto md = new QMimeData();
 213          md->setText(textCursor().selection().toPlainText());
 214          return md;
 215      }
 216  };
 217  
 218  #endif // BITCOIN_QT_RPCCONSOLE_H
 219