• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

libbitcoin / libbitcoin-server / 43291239394

12 Nov 2026 07:32PM UTC coverage: 95.172% (+0.05%) from 95.121%
43291239394

push

github

web-flow
Merge pull request #1158 from evoskuil/master

Portable configuration, bitcoind/btcd/esplora versioning.

273 of 277 new or added lines in 17 files covered. (98.56%)

3 existing lines in 1 file now uncovered.

12320 of 12945 relevant lines covered (95.17%)

417.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.18
/src/settings.cpp
1
/**
2
 * Copyright (c) 2011-2026 libbitcoin developers
3
 *
4
 * This file is part of libbitcoin.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Affero General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include <bitcoin/server/settings.hpp>
20

21
#include <filesystem>
22
#include <bitcoin/server/define.hpp>
23

24
using namespace bc::system;
25
using namespace bc::network;
26

27
namespace libbitcoin {
28

29
// log
30
// ----------------------------------------------------------------------------
31

32
namespace log {
33

34
// Log states default to network compiled states or explicit false.
35
settings::settings() NOEXCEPT
1,641 ✔
36
  : application{ levels::application_defined },
1,641 ✔
37
    news{ levels::news_defined },
1,641 ✔
38
    session{ levels::session_defined },
1,641 ✔
39
    protocol{ false /*levels::protocol_defined*/ },
1,641 ✔
40
    proxy{ false /*levels::proxy_defined*/ },
1,641 ✔
41
    remote{ levels::remote_defined },
1,641 ✔
42
    fault{ levels::fault_defined },
1,641 ✔
43
    quitting{ false /*levels::quitting_defined*/ },
1,641 ✔
44
    objects{ false /*levels::objects_defined*/ },
1,641 ✔
45
    verbose{ false /*levels::verbose_defined*/ },
1,641 ✔
46
    console{ true },
1,641 ✔
47
    events{ true },
1,641 ✔
48
    limit{ 1'000'000_u32 }
1,641 ✔
49
{
50
}
1,641 ✔
51

52
settings::settings(chain::selection) NOEXCEPT
1,640 ✔
53
  : settings()
1,640 ✔
54
{
55
}
1,640 ✔
56

57
std::filesystem::path settings::log_file1() const NOEXCEPT
2 ✔
58
{
59
    BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
60
    return console_path / "console_new.log";
2 ✔
61
    BC_POP_WARNING()
62
}
63

64
std::filesystem::path settings::log_file2() const NOEXCEPT
1 ✔
65
{
66
    BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
67
    return console_path / "console_old.log";
1 ✔
68
    BC_POP_WARNING()
69
}
70

71
std::filesystem::path settings::events_file() const NOEXCEPT
1 ✔
72
{
73
    BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
74
    return events_path / "events.log";
1 ✔
75
    BC_POP_WARNING()
76
}
77

78
} // namespace log
79

80
// server
81
// ----------------------------------------------------------------------------
82

83
namespace server {
84

85
using namespace system::wallet;
86

87
// settings::settings
88
settings::settings(system::chain::selection context,
1,670 ✔
89
    const embedded_pages& native_pages,
90
    const embedded_pages& admin_pages) NOEXCEPT
1,670 ✔
91
  : network(context),
1,670 ✔
92
    wallet(context),
1,670 ✔
93
    admin("admin", admin_pages),
1,670 ✔
94
    native("native", native_pages)
3,340 ✔
95
{
96
    // Admin is enabled by default, for the local machine only.
97
    admin.connections = 10;
1,670 ✔
98
    admin.binds.emplace_back(system::ip::ipv4::loopback(), 0_u16);
1,670 ✔
99

100
    // Admin may accumulate a large amount of log backlog.
101
    admin.maximum_backlog = 10 * network::megabyte;
1,670 ✔
102

103
    // The largest btcd notification is a filtered block.
104
    btcd.maximum_backlog = 20 * network::megabyte;
1,670 ✔
105

106
    // btcd reports json-rpc errors in the response body only.
107
    btcd.error_status = false;
1,670 ✔
108

109
    // Raw block publications drop beyond the bound, eight blocks deep.
110
    zmq.maximum_backlog = 32 * network::megabyte;
1,670 ✔
111

112
    // Subscribers send nothing after subscribing, so publishers do not expire.
113
    zmq.inactivity_minutes = 0;
1,670 ✔
114
    zmq.expiration_minutes = 0;
1,670 ✔
115

116
    // A submitted block is base16 encoded within a json envelope.
117
    constexpr auto encoded = 2 * network::max_payload + 4 * network::kilobyte;
118
    bitcoind.maximum_request = encoded;
1,670 ✔
119
    btcd.maximum_request = encoded;
1,670 ✔
120

121
    // A broadcast transaction package is base16 encoded within a json envelope.
122
    electrum.maximum_request = encoded;
1,670 ✔
123
    sparrow.maximum_request = encoded;
1,670 ✔
124
    esplora.maximum_request = encoded;
1,670 ✔
125
}
1,670 ✔
126

127
// The service contexts are read from configured files, once, at startup.
128
code settings::initialize() NOEXCEPT
1,615 ✔
129
{
130
    // Service ports are offset by chain.
131
    const auto port = [this](uint16_t base) NOEXCEPT
30,685 ✔
132
    {
133
        switch (network)
30,685 ✔
134
        {
135
            case system::chain::selection::testnet3:
×
136
                return possible_narrow_cast<uint16_t>(base + 10000_u32);
×
137
            case system::chain::selection::regtest:
95 ✔
138
                return possible_narrow_cast<uint16_t>(base + 20000_u32);
95 ✔
139
            case system::chain::selection::signet:
×
140
                return possible_narrow_cast<uint16_t>(base + 30000_u32);
×
141
            case system::chain::selection::testnet4:
57 ✔
142
                return possible_narrow_cast<uint16_t>(base + 40000_u32);
57 ✔
143
            case system::chain::selection::testnet5:
19 ✔
144
                return possible_narrow_cast<uint16_t>(base + 50000_u32);
19 ✔
145
            default:
146
                return base;
147
        }
148
    };
1,615 ✔
149

150
    admin.bind_port = port(8080);
1,615 ✔
151
    admin.safe_port = port(8043);
1,615 ✔
152
    native.bind_port = port(8180);
1,615 ✔
153
    native.safe_port = port(8143);
1,615 ✔
154
    bitcoind.bind_port = port(8280);
1,615 ✔
155
    bitcoind.safe_port = port(8243);
1,615 ✔
156
    zmq.bind_port = port(8380);
1,615 ✔
157
    zmq.safe_port = port(8343);
1,615 ✔
158
    btcd.bind_port = port(8480);
1,615 ✔
159
    btcd.safe_port = port(8443);
1,615 ✔
160
    electrum.bind_port = port(8580);
1,615 ✔
161
    electrum.safe_port = port(8543);
1,615 ✔
162
    sparrow.bind_port = port(8680);
1,615 ✔
163
    sparrow.safe_port = port(8643);
1,615 ✔
164
    esplora.bind_port = port(8780);
1,615 ✔
165
    esplora.safe_port = port(8743);
1,615 ✔
166
    stratum_v1.bind_port = port(8880);
1,615 ✔
167
    stratum_v1.safe_port = port(8843);
1,615 ✔
168
    stratum_v2.bind_port = port(8980);
1,615 ✔
169

170
    // Service bindings without a port take the service's default port.
171
    admin.default_ports();
1,615 ✔
172
    native.default_ports();
1,615 ✔
173
    bitcoind.default_ports();
1,615 ✔
174
    zmq.default_ports();
1,615 ✔
175
    btcd.default_ports();
1,615 ✔
176
    electrum.default_ports();
1,615 ✔
177
    sparrow.default_ports();
1,615 ✔
178
    esplora.default_ports();
1,615 ✔
179
    stratum_v1.default_ports();
1,615 ✔
180
    stratum_v2.default_ports();
1,615 ✔
181

182
    const auto initialize = [this](auto& service) NOEXCEPT
16,142 ✔
183
    {
184
        const auto ec = service.initialize_context();
16,142 ✔
185
        if (ec)
16,142 ✔
186
            failure = service.name;
1 ✔
187

188
        return ec;
16,142 ✔
189
    };
1,615 ✔
190

191
    if (const auto ec = initialize(admin)) return ec;
1,615 ✔
192
    if (const auto ec = initialize(native)) return ec;
1,615 ✔
193
    if (const auto ec = initialize(bitcoind)) return ec;
1,614 ✔
194
    if (const auto ec = initialize(btcd)) return ec;
1,614 ✔
195
    if (const auto ec = initialize(electrum)) return ec;
1,614 ✔
196
    if (const auto ec = initialize(sparrow)) return ec;
1,614 ✔
197
    if (const auto ec = initialize(esplora)) return ec;
1,614 ✔
198
    if (const auto ec = initialize(stratum_v1)) return ec;
1,614 ✔
199
    if (const auto ec = initialize(stratum_v2)) return ec;
1,614 ✔
200
    return initialize(zmq);
1,614 ✔
201
}
202

203
// settings::wallet_settings
204
settings::wallet_settings::wallet_settings() NOEXCEPT
1 ✔
205
  : wallet_settings(system::chain::selection::mainnet)
1 ✔
206
{
207
}
1 ✔
208

209
static const context& to_wallet_context(
3,313 ✔
210
    system::chain::selection context) NOEXCEPT
211
{
212
    switch (context)
3,313 ✔
213
    {
214
        case system::chain::selection::testnet3:
215
        case system::chain::selection::testnet4:
216
        case system::chain::selection::testnet5:
217
        case system::chain::selection::signet:
218
            return ctx::btc::test;
219
        case system::chain::selection::regtest:
13 ✔
220
            return ctx::btc::regtest;
13 ✔
221
        case system::chain::selection::mainnet:
3,280 ✔
222
        case system::chain::selection::none:
223
        default:
224
            return ctx::btc::main;
3,280 ✔
225
    }
226
}
227

228
settings::wallet_settings::wallet_settings(
3,313 ✔
229
    system::chain::selection context) NOEXCEPT
3,313 ✔
230
{
231
    const auto& value = to_wallet_context(context);
3,313 ✔
232
    p2kh_prefix = value.p2kh;
3,313 ✔
233
    p2sh_prefix = value.p2sh;
3,313 ✔
234
    wif_prefix = value.wif;
3,313 ✔
235
    witness_prefix = value.p2w;
3,313 ✔
236
    silent_prefix = value.sp;
3,313 ✔
237
    hd_private_prefix = value.hd.prv;
3,313 ✔
238
    hd_public_prefix = value.hd.pub;
3,313 ✔
239
}
3,313 ✔
240

241
context settings::wallet_settings::to_context() const NOEXCEPT
8,643 ✔
242
{
243
    return
244
    {
245
        { hd_private_prefix, hd_public_prefix },
8,643 ✔
246
        witness_prefix,
8,643 ✔
247
        p2kh_prefix,
8,643 ✔
248
        p2sh_prefix,
8,643 ✔
249
        wif_prefix,
8,643 ✔
250
        silent_prefix
8,643 ✔
251
    };
8,643 ✔
252
}
17,286 ✔
253

254
// settings::embedded_pages
255
span_value settings::embedded_pages::css()  const NOEXCEPT { return {}; }
3 ✔
256
span_value settings::embedded_pages::html() const NOEXCEPT { return {}; }
6 ✔
257
span_value settings::embedded_pages::ecma() const NOEXCEPT { return {}; }
3 ✔
258
span_value settings::embedded_pages::font() const NOEXCEPT { return {}; }
3 ✔
259
span_value settings::embedded_pages::icon() const NOEXCEPT { return {}; }
3 ✔
260
bool settings::embedded_pages::enabled() const NOEXCEPT
9 ✔
261
{
262
    return !html().empty();
9 ✔
263
}
264

265
// settings::html_server
266
settings::html_server::html_server(const std::string_view& logging_name,
3,341 ✔
267
    const embedded_pages& embedded) NOEXCEPT
3,341 ✔
268
  : network::settings::websocket_server(logging_name),
269
    pages(embedded)
3,341 ✔
270
{
271
}
3,341 ✔
272

273
// settings::bitcoind_server
274
code settings::bitcoind_server::initialize_context() NOEXCEPT
3,232 ✔
275
{
276
    using namespace interface::bitcoind;
277
    if (const auto ec = base::initialize_context())
3,232 ✔
NEW
278
        return ec;
×
279

280
    // The range is bounded by the implemented versions, and the maximum
281
    // floors to an implemented version within the range.
282
    if (protocol_minimum < minimum_version ||
6,463 ✔
283
        protocol_maximum > maximum_version ||
3,232 ✔
284
        to_value(version_floor(protocol_maximum)) < protocol_minimum)
3,230 ✔
285
        return network::error::invalid_configuration;
3 ✔
286

287
    return network::error::success;
3,229 ✔
288
}
289

290
code settings::esplora_server::initialize_context() NOEXCEPT
1,619 ✔
291
{
292
    using namespace server::esplora;
293
    if (const auto ec = base::initialize_context())
1,619 ✔
NEW
294
        return ec;
×
295

296
    // The version floors to an implemented version.
297
    if (protocol_version < minimum_version ||
1,619 ✔
298
        protocol_version > maximum_version)
299
        return network::error::invalid_configuration;
2 ✔
300

301
    return network::error::success;
1,617 ✔
302
}
303

304
} // namespace server
305

306
// ----------------------------------------------------------------------------
307

308
} // namespace libbitcoin
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc