Coverage Report

Created: 2026-10-03 10:33

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