messages.cpp raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-2022 The Limenka developers
   3  // Distributed under the MIT software license, see the accompanying
   4  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  
   6  #include <common/messages.h>
   7  
   8  #include <common/types.h>
   9  #include <policy/fees.h>
  10  #include <node/types.h>
  11  #include <tinyformat.h>
  12  #include <util/strencodings.h>
  13  #include <util/string.h>
  14  #include <util/translation.h>
  15  
  16  #include <cassert>
  17  #include <map>
  18  #include <string>
  19  #include <utility>
  20  #include <vector>
  21  
  22  using node::TransactionError;
  23  using util::Join;
  24  
  25  namespace common {
  26  std::string StringForFeeReason(FeeReason reason)
  27  {
  28      static const std::map<FeeReason, std::string> fee_reason_strings = {
  29          {FeeReason::NONE, "None"},
  30          {FeeReason::HALF_ESTIMATE, "Half Target 60% Threshold"},
  31          {FeeReason::FULL_ESTIMATE, "Target 85% Threshold"},
  32          {FeeReason::DOUBLE_ESTIMATE, "Double Target 95% Threshold"},
  33          {FeeReason::CONSERVATIVE, "Conservative Double Target longer horizon"},
  34          {FeeReason::MEMPOOL_MIN, "Mempool Min Fee"},
  35          {FeeReason::PAYTXFEE, "PayTxFee set"},
  36          {FeeReason::FALLBACK, "Fallback fee"},
  37          {FeeReason::REQUIRED, "Minimum Required Fee"},
  38      };
  39      auto reason_string = fee_reason_strings.find(reason);
  40  
  41      if (reason_string == fee_reason_strings.end()) return "Unknown";
  42  
  43      return reason_string->second;
  44  }
  45  
  46  const std::vector<std::pair<std::string, FeeEstimateMode>>& FeeModeMap()
  47  {
  48      static const std::vector<std::pair<std::string, FeeEstimateMode>> FEE_MODES = {
  49          {"unset", FeeEstimateMode::UNSET},
  50          {"economical", FeeEstimateMode::ECONOMICAL},
  51          {"conservative", FeeEstimateMode::CONSERVATIVE},
  52      };
  53      return FEE_MODES;
  54  }
  55  
  56  std::string FeeModeInfo(const std::pair<std::string, FeeEstimateMode>& mode, std::string& default_info)
  57  {
  58      switch (mode.second) {
  59          case FeeEstimateMode::UNSET:
  60              return strprintf("%s means no mode set (%s). \n", mode.first, default_info);
  61          case FeeEstimateMode::ECONOMICAL:
  62              return strprintf("%s estimates use a shorter time horizon, making them more\n"
  63                     "responsive to short-term drops in the prevailing fee market. This mode\n"
  64                     "potentially returns a lower fee rate estimate.\n", mode.first);
  65          case FeeEstimateMode::CONSERVATIVE:
  66              return strprintf("%s estimates use a longer time horizon, making them\n"
  67                     "less responsive to short-term drops in the prevailing fee market. This mode\n"
  68                     "potentially returns a higher fee rate estimate.\n", mode.first);
  69          default:
  70              // Other modes apart from the ones handled are fee rate units; they should not be clarified.
  71              assert(false);
  72      }
  73  }
  74  
  75  std::string FeeModesDetail(std::string default_info)
  76  {
  77      std::string info;
  78      for (const auto& fee_mode : FeeModeMap()) {
  79          info += FeeModeInfo(fee_mode, default_info);
  80      }
  81      return strprintf("%s \n%s", FeeModes(", "), info);
  82  }
  83  
  84  std::string FeeModes(const std::string& delimiter)
  85  {
  86      return Join(FeeModeMap(), delimiter, [&](const std::pair<std::string, FeeEstimateMode>& i) { return i.first; });
  87  }
  88  
  89  std::string InvalidEstimateModeErrorMessage()
  90  {
  91      return "Invalid estimate_mode parameter, must be one of: \"" + FeeModes("\", \"") + "\"";
  92  }
  93  
  94  bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode)
  95  {
  96      auto searchkey = ToUpper(mode_string);
  97      for (const auto& pair : FeeModeMap()) {
  98          if (ToUpper(pair.first) == searchkey) {
  99              fee_estimate_mode = pair.second;
 100              return true;
 101          }
 102      }
 103      return false;
 104  }
 105  
 106  bilingual_str PSBTErrorString(PSBTError err)
 107  {
 108      switch (err) {
 109          case PSBTError::MISSING_INPUTS:
 110              return Untranslated("Inputs missing or spent");
 111          case PSBTError::SIGHASH_MISMATCH:
 112              return Untranslated("Specified sighash value does not match value stored in PSBT");
 113          case PSBTError::EXTERNAL_SIGNER_NOT_FOUND:
 114              return Untranslated("External signer not found");
 115          case PSBTError::EXTERNAL_SIGNER_FAILED:
 116              return Untranslated("External signer failed to sign");
 117          case PSBTError::UNSUPPORTED:
 118              return Untranslated("Signer does not support PSBT");
 119          // no default case, so the compiler can warn about missing cases
 120      }
 121      assert(false);
 122  }
 123  
 124  bilingual_str TransactionErrorString(const TransactionError err)
 125  {
 126      switch (err) {
 127          case TransactionError::OK:
 128              return Untranslated("No error");
 129          case TransactionError::MISSING_INPUTS:
 130              return Untranslated("Inputs missing or spent");
 131          case TransactionError::ALREADY_IN_UTXO_SET:
 132              return Untranslated("Transaction outputs already in utxo set");
 133          case TransactionError::MEMPOOL_REJECTED:
 134              return Untranslated("Transaction rejected by mempool");
 135          case TransactionError::MEMPOOL_ERROR:
 136              return Untranslated("Mempool internal error");
 137          case TransactionError::MAX_FEE_EXCEEDED:
 138              return Untranslated("Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)");
 139          case TransactionError::MAX_BURN_EXCEEDED:
 140              return Untranslated("Unspendable output exceeds maximum configured by user (maxburnamount)");
 141          case TransactionError::INVALID_PACKAGE:
 142              return Untranslated("Transaction rejected due to invalid package");
 143          // no default case, so the compiler can warn about missing cases
 144      }
 145      assert(false);
 146  }
 147  
 148  bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBind)
 149  {
 150      return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind);
 151  }
 152  
 153  bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& invalid_value)
 154  {
 155      return strprintf(_("Invalid port specified in %s: '%s'"), optname, invalid_value);
 156  }
 157  
 158  bilingual_str AmountHighWarn(const std::string& optname)
 159  {
 160      return strprintf(_("%s is set very high!"), optname);
 161  }
 162  
 163  bilingual_str AmountErrMsg(const std::string& optname, const std::string& strValue)
 164  {
 165      return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue);
 166  }
 167  } // namespace common
 168