Coverage Report

Created: 2026-10-07 13:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/bitcoin/src/common/messages.cpp
Line
Count
Source
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
8
#include <common/types.h>
9
#include <node/types.h>
10
#include <tinyformat.h>
11
#include <util/check.h>
12
#include <util/fees.h>
13
#include <util/strencodings.h>
14
#include <util/string.h>
15
#include <util/translation.h>
16
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
const std::map<FeeReason, std::string>& FeeReasonMap()
28
6.83k
{
29
6.83k
    static const std::map<FeeReason, std::string> fee_reason_strings = {
30
6.83k
        {FeeReason::FEE_RATE_ESTIMATOR, "Fee Rate Estimator"},
31
6.83k
        {FeeReason::MEMPOOL_MIN, "Mempool Min Fee"},
32
6.83k
        {FeeReason::USER_SPECIFIED, "User Specified Fee"},
33
6.83k
        {FeeReason::FALLBACK, "Fallback fee"},
34
6.83k
        {FeeReason::REQUIRED, "Minimum Required Fee"},
35
6.83k
    };
36
6.83k
    return fee_reason_strings;
37
6.83k
}
38
39
std::string StringForFeeReason(FeeReason reason)
40
3.72k
{
41
3.72k
    const auto& fee_reason_strings = FeeReasonMap();
42
3.72k
    auto reason_string = fee_reason_strings.find(reason);
43
44
3.72k
    if (reason_string == fee_reason_strings.end()) return "Unknown";
45
46
3.72k
    return reason_string->second;
47
3.72k
}
48
49
std::string FeeReasons(const std::string& delimiter)
50
3.11k
{
51
15.5k
    return Join(FeeReasonMap(), delimiter, [](const auto& reason) { return reason.second; });
52
3.11k
}
53
54
const std::vector<std::pair<std::string, FeeEstimateMode>>& FeeModeMap()
55
29.1k
{
56
29.1k
    static const std::vector<std::pair<std::string, FeeEstimateMode>> FEE_MODES = {
57
29.1k
        {"unset", FeeEstimateMode::UNSET},
58
29.1k
        {"economical", FeeEstimateMode::ECONOMICAL},
59
29.1k
        {"conservative", FeeEstimateMode::CONSERVATIVE},
60
29.1k
    };
61
29.1k
    return FEE_MODES;
62
29.1k
}
63
64
std::string FeeModeInfo(const std::pair<std::string, FeeEstimateMode>& mode, std::string& default_info)
65
43.2k
{
66
43.2k
    switch (mode.second) {
67
14.4k
        case FeeEstimateMode::UNSET:
68
14.4k
            return strprintf("%s means no mode set (%s). \n", mode.first, default_info);
69
14.4k
        case FeeEstimateMode::ECONOMICAL:
70
14.4k
            return strprintf("%s mode potentially returns a lower fee rate estimate.\n", mode.first);
71
14.4k
        case FeeEstimateMode::CONSERVATIVE:
72
14.4k
            return strprintf("%s potentially returns a higher fee rate estimate.\n", mode.first);
73
43.2k
    } // no default case, so the compiler can warn about missing cases
74
43.2k
    assert(false);
75
0
}
76
77
std::string FeeModesDetail(std::string default_info)
78
14.4k
{
79
14.4k
    std::string info;
80
43.2k
    for (const auto& fee_mode : FeeModeMap()) {
81
43.2k
        info += FeeModeInfo(fee_mode, default_info);
82
43.2k
    }
83
14.4k
    return strprintf("%s \n%s", FeeModes(", "), info);
84
14.4k
}
85
86
std::string FeeModes(const std::string& delimiter)
87
14.4k
{
88
43.3k
    return Join(FeeModeMap(), delimiter, [&](const std::pair<std::string, FeeEstimateMode>& i) { return i.first; });
89
14.4k
}
90
91
std::string InvalidEstimateModeErrorMessage()
92
28
{
93
28
    return "Invalid estimate_mode parameter, must be one of: \"" + FeeModes("\", \"") + "\"";
94
28
}
95
96
bool FeeModeFromString(std::string_view mode_string, FeeEstimateMode& fee_estimate_mode)
97
268
{
98
268
    auto searchkey = ToUpper(mode_string);
99
572
    for (const auto& pair : FeeModeMap()) {
100
572
        if (ToUpper(pair.first) == searchkey) {
101
240
            fee_estimate_mode = pair.second;
102
240
            return true;
103
240
        }
104
572
    }
105
28
    return false;
106
268
}
107
108
bilingual_str PSBTErrorString(PSBTError err)
109
15
{
110
15
    switch (err) {
111
0
        case PSBTError::MISSING_INPUTS:
112
0
            return Untranslated("Inputs missing or spent");
113
14
        case PSBTError::SIGHASH_MISMATCH:
114
14
            return Untranslated("Specified sighash value does not match value stored in PSBT");
115
1
        case PSBTError::EXTERNAL_SIGNER_NOT_FOUND:
116
1
            return Untranslated("External signer not found");
117
0
        case PSBTError::EXTERNAL_SIGNER_FAILED:
118
0
            return Untranslated("External signer failed to sign");
119
0
        case PSBTError::UNSUPPORTED:
120
0
            return Untranslated("Signer does not support PSBT");
121
0
        case PSBTError::INCOMPLETE:
122
0
            return Untranslated("Input needs additional signatures or other data");
123
0
        case PSBTError::INVALID_TX:
124
0
            return Untranslated("The transaction cannot be valid");
125
15
    } // no default case, so the compiler can warn about missing cases
126
15
    assert(false);
127
0
}
128
129
bilingual_str TransactionErrorString(const TransactionError err)
130
37
{
131
37
    switch (err) {
132
0
        case TransactionError::OK:
133
0
            return Untranslated("No error");
134
0
        case TransactionError::MISSING_INPUTS:
135
0
            return Untranslated("Inputs missing or spent");
136
3
        case TransactionError::ALREADY_IN_UTXO_SET:
137
3
            return Untranslated("Transaction outputs already in utxo set");
138
0
        case TransactionError::MEMPOOL_REJECTED:
139
0
            return Untranslated("Transaction rejected by mempool");
140
0
        case TransactionError::MEMPOOL_ERROR:
141
0
            return Untranslated("Mempool internal error");
142
19
        case TransactionError::MAX_FEE_EXCEEDED:
143
19
            return Untranslated("Fee exceeds maximum configured by user (maxtxfee)");
144
5
        case TransactionError::MAX_FEE_RATE_EXCEEDED:
145
5
            return Untranslated("Fee rate exceeds maximum configured by user (maxfeerate)");
146
5
        case TransactionError::MAX_BURN_EXCEEDED:
147
5
            return Untranslated("Unspendable output exceeds maximum configured by user (maxburnamount)");
148
0
        case TransactionError::INVALID_PACKAGE:
149
0
            return Untranslated("Transaction rejected due to invalid package");
150
5
        case TransactionError::PRIVATE_BROADCAST_FULL:
151
5
            return Untranslated("Private broadcast queue is full");
152
37
    } // no default case, so the compiler can warn about missing cases
153
37
    assert(false);
154
0
}
155
156
bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBind)
157
3
{
158
3
    return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind);
159
3
}
160
161
bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& invalid_value)
162
13
{
163
13
    return strprintf(_("Invalid port specified in %s: '%s'"), optname, invalid_value);
164
13
}
165
166
bilingual_str AmountHighWarn(const std::string& optname)
167
9
{
168
9
    return strprintf(_("%s is set very high!"), optname);
169
9
}
170
171
bilingual_str AmountErrMsg(const std::string& optname, const std::string& strValue)
172
0
{
173
0
    return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue);
174
0
}
175
} // namespace common