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