messages.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto 2 // Copyright (c) 2009-present 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 #include <common/types.h> 8 #include <node/types.h> 9 #include <policy/fees/block_policy_estimator.h> 10 #include <tinyformat.h> 11 #include <util/fees.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::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 assert(false); 71 } 72 } 73 74 std::string FeeModesDetail(std::string default_info) 75 { 76 std::string info; 77 for (const auto& fee_mode : FeeModeMap()) { 78 info += FeeModeInfo(fee_mode, default_info); 79 } 80 return strprintf("%s \n%s", FeeModes(", "), info); 81 } 82 83 std::string FeeModes(const std::string& delimiter) 84 { 85 return Join(FeeModeMap(), delimiter, [&](const std::pair<std::string, FeeEstimateMode>& i) { return i.first; }); 86 } 87 88 std::string InvalidEstimateModeErrorMessage() 89 { 90 return "Invalid estimate_mode parameter, must be one of: \"" + FeeModes("\", \"") + "\""; 91 } 92 93 bool FeeModeFromString(std::string_view mode_string, FeeEstimateMode& fee_estimate_mode) 94 { 95 auto searchkey = ToUpper(mode_string); 96 for (const auto& pair : FeeModeMap()) { 97 if (ToUpper(pair.first) == searchkey) { 98 fee_estimate_mode = pair.second; 99 return true; 100 } 101 } 102 return false; 103 } 104 105 bilingual_str PSBTErrorString(PSBTError err) 106 { 107 switch (err) { 108 case PSBTError::MISSING_INPUTS: 109 return Untranslated("Inputs missing or spent"); 110 case PSBTError::SIGHASH_MISMATCH: 111 return Untranslated("Specified sighash value does not match value stored in PSBT"); 112 case PSBTError::EXTERNAL_SIGNER_NOT_FOUND: 113 return Untranslated("External signer not found"); 114 case PSBTError::EXTERNAL_SIGNER_FAILED: 115 return Untranslated("External signer failed to sign"); 116 case PSBTError::UNSUPPORTED: 117 return Untranslated("Signer does not support PSBT"); 118 case PSBTError::INCOMPLETE: 119 return Untranslated("Input needs additional signatures or other data"); 120 case PSBTError::OK: 121 return Untranslated("No errors"); 122 // no default case, so the compiler can warn about missing cases 123 } 124 assert(false); 125 } 126 127 bilingual_str TransactionErrorString(const TransactionError err) 128 { 129 switch (err) { 130 case TransactionError::OK: 131 return Untranslated("No error"); 132 case TransactionError::MISSING_INPUTS: 133 return Untranslated("Inputs missing or spent"); 134 case TransactionError::ALREADY_IN_UTXO_SET: 135 return Untranslated("Transaction outputs already in utxo set"); 136 case TransactionError::MEMPOOL_REJECTED: 137 return Untranslated("Transaction rejected by mempool"); 138 case TransactionError::MEMPOOL_ERROR: 139 return Untranslated("Mempool internal error"); 140 case TransactionError::MAX_FEE_EXCEEDED: 141 return Untranslated("Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)"); 142 case TransactionError::MAX_BURN_EXCEEDED: 143 return Untranslated("Unspendable output exceeds maximum configured by user (maxburnamount)"); 144 case TransactionError::INVALID_PACKAGE: 145 return Untranslated("Transaction rejected due to invalid package"); 146 // no default case, so the compiler can warn about missing cases 147 } 148 assert(false); 149 } 150 151 bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBind) 152 { 153 return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind); 154 } 155 156 bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& invalid_value) 157 { 158 return strprintf(_("Invalid port specified in %s: '%s'"), optname, invalid_value); 159 } 160 161 bilingual_str AmountHighWarn(const std::string& optname) 162 { 163 return strprintf(_("%s is set very high!"), optname); 164 } 165 166 bilingual_str AmountErrMsg(const std::string& optname, const std::string& strValue) 167 { 168 return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue); 169 } 170 } // namespace common