kernel_notifications.cpp raw

   1  // Copyright (c) 2023-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  #include <node/kernel_notifications.h>
   6  
   7  #include <bitcoin-build-config.h> // IWYU pragma: keep
   8  
   9  #include <chain.h>
  10  #include <common/args.h>
  11  #include <common/system.h>
  12  #include <kernel/context.h>
  13  #include <kernel/warning.h>
  14  #include <node/abort.h>
  15  #include <node/interface_ui.h>
  16  #include <node/warnings.h>
  17  #include <util/check.h>
  18  #include <util/log.h>
  19  #include <util/signalinterrupt.h>
  20  #include <util/strencodings.h>
  21  #include <util/string.h>
  22  #include <util/translation.h>
  23  
  24  #include <cstdint>
  25  #include <string>
  26  #include <thread>
  27  
  28  using util::ReplaceAll;
  29  
  30  static void AlertNotify(const std::string& strMessage)
  31  {
  32  #if HAVE_SYSTEM
  33      std::string strCmd = gArgs.GetArg("-alertnotify", "");
  34      if (strCmd.empty()) return;
  35  
  36      // Alert text should be plain ascii coming from a trusted source, but to
  37      // be safe we first strip anything not in safeChars, then add single quotes around
  38      // the whole string before passing it to the shell:
  39      std::string singleQuote("'");
  40      std::string safeStatus = SanitizeString(strMessage);
  41      safeStatus = singleQuote+safeStatus+singleQuote;
  42      ReplaceAll(strCmd, "%s", safeStatus);
  43  
  44      std::thread t(runCommand, strCmd);
  45      t.detach(); // thread runs free
  46  #endif
  47  }
  48  
  49  namespace node {
  50  
  51  kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state, const CBlockIndex& index, double verification_progress)
  52  {
  53      {
  54          LOCK(m_tip_block_mutex);
  55          Assume(index.GetBlockHash() != uint256::ZERO);
  56          m_state.tip_block = index.GetBlockHash();
  57          m_tip_block_cv.notify_all();
  58      }
  59  
  60      uiInterface.NotifyBlockTip(state, index, verification_progress);
  61      if (m_stop_at_height && index.nHeight >= m_stop_at_height) {
  62          if (!m_shutdown_request()) {
  63              LogError("Failed to send shutdown signal after reaching stop height\n");
  64          }
  65          return kernel::Interrupted{};
  66      }
  67      return {};
  68  }
  69  
  70  void KernelNotifications::headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync)
  71  {
  72      uiInterface.NotifyHeaderTip(state, height, timestamp, presync);
  73  }
  74  
  75  void KernelNotifications::progress(const bilingual_str& title, int progress_percent, bool resume_possible)
  76  {
  77      uiInterface.ShowProgress(title.translated, progress_percent, resume_possible);
  78  }
  79  
  80  void KernelNotifications::warningSet(kernel::Warning id, const bilingual_str& message)
  81  {
  82      if (m_warnings.Set(id, message)) {
  83          AlertNotify(message.original);
  84      }
  85  }
  86  
  87  void KernelNotifications::warningUnset(kernel::Warning id)
  88  {
  89      m_warnings.Unset(id);
  90  }
  91  
  92  void KernelNotifications::flushError(const bilingual_str& message)
  93  {
  94      AbortNode(m_shutdown_request, m_exit_status, message, &m_warnings);
  95  }
  96  
  97  void KernelNotifications::fatalError(const bilingual_str& message)
  98  {
  99      node::AbortNode(m_shutdown_on_fatal_error ? m_shutdown_request : nullptr,
 100                      m_exit_status, message, &m_warnings);
 101  }
 102  
 103  std::optional<uint256> KernelNotifications::TipBlock()
 104  {
 105      AssertLockHeld(m_tip_block_mutex);
 106      return m_state.tip_block;
 107  };
 108  
 109  
 110  void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications)
 111  {
 112      if (auto value{args.GetIntArg("-stopatheight")}) notifications.m_stop_at_height = *value;
 113  }
 114  
 115  } // namespace node
 116