Coverage Report

Created: 2026-09-14 20:36

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.68k
{
29
3.68k
    static const std::map<FeeReason, std::string> fee_reason_strings = {
30
3.68k
        {FeeReason::FEE_RATE_ESTIMATOR, "Fee Rate Estimator"},
31
3.68k
        {FeeReason::MEMPOOL_MIN, "Mempool Min Fee"},
32
3.68k
        {FeeReason::USER_SPECIFIED, "User Specified Fee"},
33
3.68k
        {FeeReason::FALLBACK, "Fallback fee"},
34
3.68k
        {FeeReason::REQUIRED, "Minimum Required Fee"},
35
3.68k
    };
36
3.68k
    auto reason_string = fee_reason_strings.find(reason);
37
38
3.68k
    if (reason_string == fee_reason_strings.end()) return "Unknown";
39
40
3.68k
    return reason_string->second;
41
3.68k
}
42
43
const std::vector<std::pair<std::string, FeeEstimateMode>>& FeeModeMap()
44
28.1k
{
45
28.1k
    static const std::vector<std::pair<std::string, FeeEstimateMode>> FEE_MODES = {
46
28.1k
        {"unset", FeeEstimateMode::UNSET},
47
28.1k
        {"economical", FeeEstimateMode::ECONOMICAL},
48
28.1k
        {"conservative", FeeEstimateMode::CONSERVATIVE},
49
28.1k
    };
50
28.1k
    return FEE_MODES;
51
28.1k
}
52
53
std::string FeeModeInfo(const std::pair<std::string, FeeEstimateMode>& mode, std::string& default_info)
54
41.8k
{
55
41.8k
    switch (mode.second) {
56
13.9k
        case FeeEstimateMode::UNSET:
57
13.9k
            return strprintf("%s means no mode set (%s). \n", mode.first, default_info);
58
13.9k
        case FeeEstimateMode::ECONOMICAL:
59
13.9k
            return strprintf("%s mode potentially returns a lower fee rate estimate.\n", mode.first);
60
13.9k
        case FeeEstimateMode::CONSERVATIVE:
61
13.9k
            return strprintf("%s potentially returns a higher fee rate estimate.\n", mode.first);
62
41.8k
    } // no default case, so the compiler can warn about missing cases
63
41.8k
    assert(false);
64
0
}
65
66
std::string FeeModesDetail(std::string default_info)
67
13.9k
{
68
13.9k
    std::string info;
69
41.8k
    for (const auto& fee_mode : FeeModeMap()) {
70
41.8k
        info += FeeModeInfo(fee_mode, default_info);
71
41.8k
    }
72
13.9k
    return strprintf("%s \n%s", FeeModes(", "), info);
73
13.9k
}
74
75
std::string FeeModes(const std::string& delimiter)
76
13.9k
{
77
41.9k
    return Join(FeeModeMap(), delimiter, [&](const std::pair<std::string, FeeEstimateMode>& i) { return i.first; });
78
13.9k
}
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
250
{
87
250
    auto searchkey = ToUpper(mode_string);
88
536
    for (const auto& pair : FeeModeMap()) {
89
536
        if (ToUpper(pair.first) == searchkey) {
90
222
            fee_estimate_mode = pair.second;
91
222
            return true;
92
222
        }
93
536
    }
94
28
    return false;
95
250
}
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
35
{
120
35
    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
22
        case TransactionError::MAX_FEE_EXCEEDED:
132
22
            return Untranslated("Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)");
133
5
        case TransactionError::MAX_BURN_EXCEEDED:
134
5
            return Untranslated("Unspendable output exceeds maximum configured by user (maxburnamount)");
135
0
        case TransactionError::INVALID_PACKAGE:
136
0
            return Untranslated("Transaction rejected due to invalid package");
137
5
        case TransactionError::PRIVATE_BROADCAST_FULL:
138
5
            return Untranslated("Private broadcast queue is full");
139
35
    } // no default case, so the compiler can warn about missing cases
140
35
    assert(false);
141
0
}
142
143
bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBind)
144
3
{
145
3
    return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind);
146
3
}
147
148
bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& invalid_value)
149
13
{
150
13
    return strprintf(_("Invalid port specified in %s: '%s'"), optname, invalid_value);
151
13
}
152
153
bilingual_str AmountHighWarn(const std::string& optname)
154
7
{
155
7
    return strprintf(_("%s is set very high!"), optname);
156
7
}
157
158
bilingual_str AmountErrMsg(const std::string& optname, const std::string& strValue)
159
0
{
160
0
    return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue);
161
0
}
162
} // namespace common