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