Coverage Report

Created: 2025-06-10 13:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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