Archive of the libbitcoin Slack #general channel.
libbitcoin-server and the bitcoin-server (bs) console builds from libbitcoin-node and bitcoin-node (bn). This means there is no longer a bn console application. node is now a dependency of server, and server provides the console application. The node and server libraries are about the same size, and splitting them has simplified and better organized the code and sped up the individual builds. The only difference for general usage is that the install.sh from the libbitcoin-server must be used, the console application is bs, and the log file names are bs_begin.log and bs_end.log. Config settings were already organized with the anticipated (server) names, so there is no impact to settings.secp256k1 NuGet package, adding a proper versioned release for the outdated version we have been using for the past year, and also a release that tracks with the current release.
https://www.nuget.org/packages/secp256k1_vc143ltcg binaries to the current vc++ compiler that I'm using and therefore enables this scenario.SOCKS5 for [outbound] and [manual] (p2p) connections. These are configured independently (and there is no inbound p2p or incoming service endpoint support).
[outbound] socks = localhost:1080 username = foo password = bar [manual] socks = localhost:1080 username = password =


connector::handle_connect(...) and connector::start(...) protected base class methods and implements the indirection on the socket strand. https://github.com/evoskuil/libbitcoin-network/blob/master/src/net/connector_socks.cppshinysocks https://github.com/jgaa/shinysocks and Wireshark for traffic analysis.LTCG in vc++ and ran some performance tests. Noticeably worse, and the binary was even slightly larger. So that's back on ice.Tor and I2P support. So that's now implemented, with the exception of gossiping onion and garlic host addresses via p2p. That just requires processing of the address_v2 message, with updates to the address pool.SOCKS5 through Tor now, with and without password authentication. Tor is one of the easy ways to functionally verify this, as it accepts any username/password, or not, which are distinct protocols. Also the issue of the socks proxy being identified as the endpoint authority is now resolved, using the configured endpoint to address as the outbound authority when proxied.[outbound] socks = localhost:9050 connections = 50 connect_batch_size = 1 [network] connect_timeout_seconds = 15 handshake_timeout_seconds = 15
[node] allowed_deviation = 2.0
loopback over the simple ShinySocks proxy:
2026-01-05T06:02:24Z.0 Node is running. 2026-01-05T06:02:26Z.2 Accepted peer connection [127.0.0.1:61716] on binding [0.0.0.0:8333]. 2026-01-05T06:02:26Z.1 Outbound [127.0.0.1:8333] version (70015) "/Satoshi:0.14.2/" 2026-01-05T06:02:26Z.1 Inbound [127.0.0.1:61716] version (70015) "/Satoshi:0.14.2/" 2026-01-05T06:02:26Z.2 Manual channel start [127.0.0.1:8333] success
2026-01-05 01:01:49.572 Eastern Standard Time INFO 61612 ShinySocks 1.4.0 starting up. Log level: 2026-01-05 01:01:49.579 Eastern Standard Time INFO 61612 Resolving host=0.0.0.0, port=1080 2026-01-05 01:01:49.585 Eastern Standard Time INFO 61612 Listener on 0.0.0.0:1080 2026-01-05 01:02:26.151 Eastern Standard Time INFO 33196 Incoming connection on socket. 2026-01-05 01:02:26.156 Eastern Standard Time INFO 24472 Proxy starting on socket 127.0.0.1:1080<-->127.0.0.1:61715 2026-01-05 01:02:26.161 Eastern Standard Time INFO 24472 ParseV5Header: Will try to connect to: 127.0.0.1 2026-01-05 01:02:26.167 Eastern Standard Time INFO 24472 Connecting to endpoint 127.0.0.1:8333
Tor doesn't like the loopback:
Jan 05 01:11:56.000 [warn] Rejecting SOCKS request for anonymous connection to private address [scrubbed].
[node] user_agent = "/Satoshi:0.14.2/"(edited)
manual.peer and outbound.seed) will not resolve when passed via a proxy. I'll deal with this when I add onion/garlic resolution and address gossip.872,646 at 10.7 hours over Tor. That's about twice as fast as Core on the same machine without Tor. When it hits 900k I'll plot the data, but it looks to have been pretty constant all night. Full validation would be about the same time, since maxi only needs 4.2 hours to validate.[log]
path = {logdir}
[bitcoin]
# Regtest genesis block (hex-encoded)
genesis_block = {genesis_hex}
# Regtest proof of work limit (0x207fffff = 545259519)
proof_of_work_limit = 545259519
# Accept any valid chain (no minimum work requirement)
minimum_work = 0000000000000000000000000000000000000000000000000000000000000000
[forks]
# Regtest allows easy mining without real proof of work
difficult = false
[network]
# Regtest network magic (0xDAB5BFFA = 3669344250)
identifier = 3669344250
[inbound]
# Listen for P2P connections
bind = 127.0.0.1:{p2p_port}
connections = 10
enable_loopback = true
[outbound]
# Disable outbound connections to prevent contacting mainnet seeds
connections = 0
host_pool_capacity = 0
[database]
path = {datadir}
# Tiny regtest DB profile (avoid multi-GB prealloc).
header_buckets = 1
header_size = 1000
txs_buckets = 1
txs_size = 1000
tx_buckets = 1
tx_size = 1000
point_buckets = 1
point_size = 1000
strong_tx_buckets = 1
strong_tx_size = 1000
input_size = 1000
ins_size = 1000
output_size = 1000
outs_size = 1000
candidate_size = 1000
confirmed_size = 1000
duplicate_buckets = 1
duplicate_size = 100
prevout_buckets = 0
prevout_size = 1
validated_bk_buckets = 1
validated_bk_size = 1000
validated_tx_buckets = 1
validated_tx_size = 1000
address_buckets = 1
address_size = 1000
filter_bk_buckets = 0
filter_tx_buckets = 0
[node]
# Don't delay inbound peers waiting for "current" chain state (regtest genesis is old).
delay_inbound = falsesocks5 work. This generalizes the socket address handling so that both numeric and non-numeric (fqdn) addresses remain supported for both proxied and unproxied connections. Previously the presumption was that the far end of the connection was always resolvable to its IP address, which was used for certain aspects of peer tracking and logging. This is now generalized to non-IP names. This is necessary because under a proxy the name resolution should occur at the proxy, and the resolved IP address is not necessarily returned to the caller under socks5 (e.g. Tor proxy). Given this change address tracking is now based on the outgoing config::endpoint as opposed to the outgoing config::authority. And the resolved IP address remains used only for differentiating incoming connections.52.8 mins to block 900,000. This just my periodic check to make sure changes aren't causing some unexpected hit. This build incorporated generalizations of the socket class to simplify secure transport integration for each of the transport protocols (zmq and sv2 stubbed in but deferred): p2p/s, http/s, ws/s, zmq/s, rpc/s, sv2/s./v1/tx/[hash]/details:
{
"wtxid": "e327dd4ebd756a127b8e9c630f43ed870eb0e248767f99b629d4f11a601b200b",
"segregated": true,
"coinbase": false,
"nominal": 157,
"maximal": 373,
"weight": 844,
"value": 345274,
"spend": 344809,
"fee": 465,
"confirmed": {
"height": 900000,
"position": 500,
"sigops": 6
}
}/v1/configuration:
{
"address": false,
"filter": false,
"turbo": true,
"witness": true,
"retarget": true,
"difficult": true
}/v1/block/hash/[hash]/header/context:
{
"hash": "00000000000000000000a53fede899a452adc99a5fa732ce218be735e734c65a",
"height": 905112,
"mtp": 1752256704,
"state": {
"wire": 1676772,
"count": 1952,
"validated": true,
"confirmed": true,
"confirmable": true,
"unconfirmable": false
},
"forks": {
"bip30": false,
"bip34": true,
"bip66": true,
"bip65": true,
"bip90": true,
"bip68": true,
"bip112": true,
"bip113": true,
"bip141": true,
"bip143": true,
"bip147": true,
"bip42": true,
"bip341": true,
"bip342": true
}
}/v1/block/hash/[hash]/details:
{
"hash": "00000000000000000000a53fede899a452adc99a5fa732ce218be735e734c65a",
"height": 905112,
"count": 1952,
"sigops": 7837,
"segregated": true,
"nominal": 772126,
"maximal": 1676772,
"weight": 3993150,
"fees": 2549618,
"subsidy": 312500000,
"reward": 315049618,
"claim": 315049618
} (edited)/v1/block/height/[height]/... of course.TLS support for http, websockets, electrum, and stratum-v1 by next week. Maybe another week for bip324.wolfssl sources into libbitcoin-network. This is quite a large library, but has an integrated openssl compat layer, and a GPLv3 license, which allows it to drop in to the boost::beast::ssl::stream template. A large number of the source file can be removed once it's all working and we know exactly what the requirements are. Given the openssl interface, it should be possible to replace it with another implementation or even roll our own behind the interface at some point.boost::asio::ssl::socket defined. Next step is to drop the new socket type into the socket class member variant to support http/s, ws/s and rpc/s.------------------------------------------------------------------------------ wolfSSL version 5.8.4 ------------------------------------------------------------------------------ macro test passed! error test passed! MEMORY test passed! base64 test passed! base16 test passed! asn test passed! SHA-256 test passed! RANDOM test passed! Hash test passed! HMAC-SHA256 test passed! HMAC-KDF test passed! TLSv1.2 KDF test passed! TLSv1.3 KDF test passed! Chacha test passed! POLY1305 test passed! ChaCha20-Poly1305 AEAD test passed! OPENSSL test passed! OPENSSL (EVP MD) passed! OPENSSL (PKEY0) passed! OPENSSL (PKEY1) passed! OPENSSL (EVP Sign/Verify) passed! ECC test passed! CURVE25519 test passed! logging test passed! time test passed! mutex test passed! memcb test passed! crypto callback test passed! Test complete *** No errors detected
#ifndef LIBBITCOIN_NETWORK_SSL_WOLFSSL_WOLFCRYPT_USER_SETINGS_H
#define LIBBITCOIN_NETWORK_SSL_WOLFSSL_WOLFCRYPT_USER_SETINGS_H
/* This file is imported into all wolfssl sources when WOLFSSL_USER_SETTINGS */
/* is defined, which is done at project scope. This is also imported by boost */
/* asio via options.h import when BOOST_ASIO_USE_WOLFSSL is defined. */
/* The /ssl/openssl/ directory is provided for direct import by boost when */
/* #include <boost/asio/ssl.hpp> is specified, forwarding to wolfssl headers. */
/* This build has no dependency on any libbitcoin sources. */
/* #include <bitcoin/network/define.hpp> */
#if defined(_MSC_VER)
/* C99 variable-length arrays (VLAs) are not supported by MSVC. */
#define WOLFSSL_SP_NO_DYN_STACK
/* Avoid conflict with min/max compatibility macros. */
#define WOLFSSL_HAVE_MIN
#define WOLFSSL_HAVE_MAX
#endif
/* Documentation for the options below. */
/* wolfssl.com/documentation/manuals/wolfssl/chapter02.html */
/* In a library build, "HAVE_" symbols are set on the command line. But since */
/* this is embedded they are set here just as with "NO_", "WC_" and "WOLFSSL_". */
/* Used with BOOST_ASIO_USE_WOLFSSL to optimize boost integration. */
/* wolfssl.com/wolfssl-support-asio-boost-asio-c-libraries */
#define WOLFSSL_ASIO
/* Suppress warnings on unnecessary file inclusions. */
#define WOLFSSL_IGNORE_FILE_WARN
/* wolfssl.com/documentation/manuals/wolfssl/chapter05.html */
/* Requires that send and receive data copy functions be defined. */
/* #define WOLFSSL_USER_IO */
/* No reason to define this as the library does not use sockets (test only). */
/* #define WOLFSSL_NO_SOCK */
/* Required by boost for certificate management via filesystem. */
/* #define NO_FILESYSTEM */
#define WOLFSSL_PEM_TO_DER
#define WOLFSSL_CERT_GEN
#define WOLFSSL_DER_LOAD
#define WOLFSSL_KEY_GEN
/* TLS is required, not just cryptographic functions. */
#define WOLFSSL_TLS13
/* At least one encryption method is required. */
/* ECC is needed for Curve25519-based key exchange in modern TLS. */
#define HAVE_SUPPORTED_CURVES
#define HAVE_TLS_EXTENSIONS
#define HAVE_CURVE25519
#define HAVE_POLY1305
#define HAVE_CHACHA
#define HAVE_SHA256
#define HAVE_HKDF
#define HAVE_HMAC
#define HAVE_ECC
/* Callback requires at least one union element to be defined. */
#define WOLF_CRYPTO_CB
/* This removes default RNG fallback (must set a callback RNG). */
/* #define WC_NO_HASHDRBG */
/* On Windows OS RNG APIs are used, these on others. */
/* #define NO_DEV_RANDOM */
/* #define NO_DEV_URANDOM */
/* These are openssl settings that affect wolfssl and/or boost asio. */
#define OPENSSL_VERSION_NUMBER 0x10101000L
#define OPENSSL_NO_ENGINE
#define OPENSSL_NO_SSL3
#define OPENSSL_NO_SSL2
#define OPENSSL_EXTRA
/* Side-channel protection is not required. */
/* #define WOLFSSL_HARDEN_TLS 128 */
#define NO_ECC_TIMING_RESISTANT
#define NO_TFM_TIMING_RESISTANT
#define WC_NO_HARDEN
/* Remove unused or undesired components. */
#define WOLFSSL_NO_CLIENT_AUTH
#define NO_SESSION_CACHE
#define NO_OLD_TLS
#define NO_OCSP
#define NO_DES3
#define NO_PSK
#define NO_AES
#define NO_SHA
#define NO_DSA
#define NO_RSA
#define NO_MD4
#define NO_MD5
#define NO_RC4
#define NO_DH
#ifdef _MSC_VER
/* Warnings emitted due to missing define in vc++. */
#define WC_MAYBE_UNUSED __pragma(warning(suppress:4505))
/* Build break in test_ossl_bio.c due to missing define in vc++. */
#ifndef STDERR_FILENO
#define STDERR_FILENO _fileno(stderr)
#endif
#endif
#ifndef NDEBUG
#define DEBUG_WOLFSSL
#define DEBUG_SUITE_TESTS
////#define WOLFSSL_VERBOSE_ERRORS
#define WOLFSSL_HAVE_ERROR_QUEUE
#ifndef WOLFSSL_LOGGINGENABLED_DEFAULT
#define WOLFSSL_LOGGINGENABLED_DEFAULT 1
#endif
#ifndef WOLFSSL_CERT_LOG_ENABLED_DEFAULT
#define WOLFSSL_CERT_LOG_ENABLED_DEFAULT 1
#endif
#endif
#define NO_MAIN_DRIVER
#define NO_TESTSUITE_MAIN_DRIVER
#define CERT_WRITE_TEMP_DIR "./"
#endif#if defined(WITH_SSL) #define HAVE_SSL #define BOOST_ASIO_USE_WOLFSSL #include <boost/asio/ssl.hpp> #endif // WITH_SSL
namespace ssl {
typedef boost::asio::ssl::context context;
typedef boost::asio::ssl::stream<asio::socket> socket;
// Just testing out the ssl socket compile.
inline void foobar() THROWS
{
io_context my_io_context{};
context my_ssl_context{ context::tlsv12_server };
socket my_ssl_socket{ my_io_context, my_ssl_context };
}
} // namespace ssltrying server command line[77]: SuiteTest -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -c ./certs/server-ecc.pem -k ./certs/ecc-key.pem -2 connecting to 127.0.0.1:11111 peer has no cert! listening on port 11111 connecting to 127.0.0.1:11111 peer has no cert! trying client command line[78]: SuiteTest -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -A ./certs/ca-ecc-cert.pem -2 -H defCipherList Using default cipher list for testing SSL version is TLSv1.3 SSL cipher suite is TLS_CHACHA20_POLY1305_SHA256 SSL signature algorithm is SHA256 SSL curve name is SECP256R1 Server Random : AE540D93436BD8426610F184B069CB53A22E15B7203E9E041C55C9A91CE86011 Alternate cert chain used issuer : /C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com/emailAddress=info@wolfssl.com subject: /C=US/ST=Washington/L=Seattle/O=Elliptic/OU=ECC/CN=www.wolfssl.com/emailAddress=info@wolfssl.com serial number:03 SSL version is TLSv1.3 SSL cipher suite is TLS_CHACHA20_POLY1305_SHA256 SSL signature algorithm is (null) SSL curve name is SECP256R1 --- Server certificate -----BEGIN CERTIFICATE----- MIICozCCAkigAwIBAgIBAzAKBggqhkjOPQQDAjCBlzELMAkGA1UEBhMCVVMxEzAR BgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dv bGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYDVQQDDA93d3cud29sZnNz bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjUxMTEz MjA0MTE1WhcNMjgwODA5MjA0MTE1WjCBkDELMAkGA1UEBhMCVVMxEzARBgNVBAgM Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxETAPBgNVBAoMCEVsbGlwdGlj MQwwCgYDVQQLDANFQ0MxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH A0IABLszrEwnUErGSqUEwzzenzbbci3OlOor+ssgCTksFuhhAumvTdMCk5oxW5eS IX/wzxjakRECNIboIFgzC4A0idijgYkwgYYwHQYDVR0OBBYEFF1dJu+sfjb5m3YV K0olAiPvsokwMB8GA1UdIwQYMBaAFFaOmsPwQt4YuUVVbvmTz+rD86UhMAwGA1Ud EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBEG CWCGSAGG+EIBAQQEAwIGQDAKBggqhkjOPQQDAgNJADBGAiEA+C/0OZkZlxE3n9jX fwSmynRZmv4wW03lMQZVnOj2tHECIQChUslyicZPIue/l2jc/32XFQWd2FYp9d/e py2Q0cUnMA== -----END CERTIFICATE----- Session timeout set to 500 seconds Client Random : 32674149ACF0D86723D6096BA57CE61869932685A9B03DF65F9A79326F7EBE52 Client message: hello wolfssl! I hear you fa shizzle! repeating test with non blocking on trying server command line[79]: SuiteTest -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -c ./certs/server-ecc.pem -k ./certs/ecc-key.pem -2 -N trying client command line[80]: SuiteTest -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -A ./certs/ca-ecc-cert.pem -2 -N ... client would read block ... client would read block ... client would read block Alternate cert chain used issuer : /C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com/emailAddress=info@wolfssl.com subject: /C=US/ST=Washington/L=Seattle/O=Elliptic/OU=ECC/CN=www.wolfssl.com/emailAddress=info@wolfssl.com serial number:03 SSL version is TLSv1.3 SSL cipher suite is TLS_CHACHA20_POLY1305_SHA256 SSL signature algorithm is (null) SSL curve name is SECP256R1 SSL version is TLSv1.3 SSL cipher suite is TLS_CHACHA20_POLY1305_SHA256 --- Server certificate SSL signature algorithm is SHA256 SSL curve name is SECP256R1 Server Random : 6981CA62172E2CA4A8048C0C67AE805406986BFEBA240D0368A9854649A31789 -----BEGIN CERTIFICATE----- MIICozCCAkigAwIBAgIBAzAKBggqhkjOPQQDAjCBlzELMAkGA1UEBhMCVVMxEzAR BgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dv bGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYDVQQDDA93d3cud29sZnNz bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjUxMTEz MjA0MTE1WhcNMjgwODA5MjA0MTE1WjCBkDELMAkGA1UEBhMCVVMxEzARBgNVBAgM Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxETAPBgNVBAoMCEVsbGlwdGlj MQwwCgYDVQQLDANFQ0MxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH A0IABLszrEwnUErGSqUEwzzenzbbci3OlOor+ssgCTksFuhhAumvTdMCk5oxW5eS IX/wzxjakRECNIboIFgzC4A0idijgYkwgYYwHQYDVR0OBBYEFF1dJu+sfjb5m3YV K0olAiPvsokwMB8GA1UdIwQYMBaAFFaOmsPwQt4YuUVVbvmTz+rD86UhMAwGA1Ud EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBEG CWCGSAGG+EIBAQQEAwIGQDAKBggqhkjOPQQDAgNJADBGAiEA+C/0OZkZlxE3n9jX fwSmynRZmv4wW03lMQZVnOj2tHECIQChUslyicZPIue/l2jc/32XFQWd2FYp9d/e py2Q0cUnMA== -----END CERTIFICATE----- Session timeout set to 500 seconds Client Random : CEFBB6F323090BBCE2BBE541144C41DD668872FC109DD8DF42A682DB5ECCF9CF Client message: hello wolfssl! I hear you fa shizzle! listening on port 11111 connecting to 127.0.0.1:11111 peer has no cert! listening on port 11111 connecting to 127.0.0.1:11111 peer has no cert! repeating test with client cert request off trying server command line[81]: SuiteTest -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -c ./certs/server-ecc.pem -k ./certs/ecc-key.pem -2 -d trying client command line[82]: SuiteTest -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -A ./certs/ca-ecc-cert.pem -2 SSL version is TLSv1.3 SSL cipher suite is TLS_CHACHA20_POLY1305_SHA256 SSL signature algorithm is SHA256 SSL curve name is SECP256R1 Server Random : 9ECD0D77EFA48587436326450557A0526CF2BFBC2E346F1DE5A16AA4B4BEFE4D Alternate cert chain used issuer : /C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com/emailAddress=info@wolfssl.com subject: /C=US/ST=Washington/L=Seattle/O=Elliptic/OU=ECC/CN=www.wolfssl.com/emailAddress=info@wolfssl.com serial number:03 SSL version is TLSv1.3 SSL cipher suite is TLS_CHACHA20_POLY1305_SHA256 SSL signature algorithm is (null) SSL curve name is SECP256R1 --- Server certificate -----BEGIN CERTIFICATE----- MIICozCCAkigAwIBAgIBAzAKBggqhkjOPQQDAjCBlzELMAkGA1UEBhMCVVMxEzAR BgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dv bGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYDVQQDDA93d3cud29sZnNz bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjUxMTEz MjA0MTE1WhcNMjgwODA5MjA0MTE1WjCBkDELMAkGA1UEBhMCVVMxEzARBgNVBAgM Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxETAPBgNVBAoMCEVsbGlwdGlj MQwwCgYDVQQLDANFQ0MxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH A0IABLszrEwnUErGSqUEwzzenzbbci3OlOor+ssgCTksFuhhAumvTdMCk5oxW5eS IX/wzxjakRECNIboIFgzC4A0idijgYkwgYYwHQYDVR0OBBYEFF1dJu+sfjb5m3YV K0olAiPvsokwMB8GA1UdIwQYMBaAFFaOmsPwQt4YuUVVbvmTz+rD86UhMAwGA1Ud EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBEG CWCGSAGG+EIBAQQEAwIGQDAKBggqhkjOPQQDAgNJADBGAiEA+C/0OZkZlxE3n9jX fwSmynRZmv4wW03lMQZVnOj2tHECIQChUslyicZPIue/l2jc/32XFQWd2FYp9d/e py2Q0cUnMA== -----END CERTIFICATE----- Session timeout set to 500 seconds Client Random : 8630606A7C9B7095E3038FFE08F7D3221EB0207C907A14188B000BEDDC6DC464 Client message: hello wolfssl! I hear you fa shizzle! repeating test with client cert request off repeating test with non blocking on trying server command line[83]: SuiteTest -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -c ./certs/server-ecc.pem -k ./certs/ecc-key.pem -2 -d -N trying client command line[84]: SuiteTest -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -A ./certs/ca-ecc-cert.pem -2 -N ... client would read block ... client would read block ... client would read block ... client would read block SSL version is TLSv1.3 SSL cipher suite is TLS_CHACHA20_POLY1305_SHA256 SSL signature algorithm is SHA256 SSL curve name is SECP256R1 Server Random : 7AAFED592B0561EFF53C5F37A80B93A0CF77A79EACDE60205EB3BE9E4E698C85 Alternate cert chain used issuer : /C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com/emailAddress=info@wolfssl.com subject: /C=US/ST=Washington/L=Seattle/O=Elliptic/OU=ECC/CN=www.wolfssl.com/emailAddress=info@wolfssl.com serial number:03 SSL version is TLSv1.3 SSL cipher suite is TLS_CHACHA20_POLY1305_SHA256 SSL signature algorithm is (null) SSL curve name is SECP256R1 --- Server certificate -----BEGIN CERTIFICATE----- MIICozCCAkigAwIBAgIBAzAKBggqhkjOPQQDAjCBlzELMAkGA1UEBhMCVVMxEzAR BgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dv bGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYDVQQDDA93d3cud29sZnNz bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjUxMTEz MjA0MTE1WhcNMjgwODA5MjA0MTE1WjCBkDELMAkGA1UEBhMCVVMxEzARBgNVBAgM Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxETAPBgNVBAoMCEVsbGlwdGlj MQwwCgYDVQQLDANFQ0MxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH A0IABLszrEwnUErGSqUEwzzenzbbci3OlOor+ssgCTksFuhhAumvTdMCk5oxW5eS IX/wzxjakRECNIboIFgzC4A0idijgYkwgYYwHQYDVR0OBBYEFF1dJu+sfjb5m3YV K0olAiPvsokwMB8GA1UdIwQYMBaAFFaOmsPwQt4YuUVVbvmTz+rD86UhMAwGA1Ud EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBEG CWCGSAGG+EIBAQQEAwIGQDAKBggqhkjOPQQDAgNJADBGAiEA+C/0OZkZlxE3n9jX fwSmynRZmv4wW03lMQZVnOj2tHECIQChUslyicZPIue/l2jc/32XFQWd2FYp9d/e py2Q0cUnMA== -----END CERTIFICATE----- Session timeout set to 500 seconds Client Random : 30AAF3DE24B255B5DCC79D57226ECC5518A944A968EA57AF3B7FE55DDE5F1F9E Client message: hello wolfssl! I hear you fa shizzle! starting TLSv13 Downgrade extra tests starting certificate chain cipher suite tests starting dh prime tests starting tests that expect failure Success -- All results as expected. End Cipher Suite Tests *** No errors detected
51.9 mins to milestone 900,000 (previous 52.8 min). Mini still holds the overall record at 48 mins but I don't run it as often.boost::asio::ssl. We don't even reference it anywhere in the code. And dependent libraries pick it up as well. However it can be configured in the vc++ (visual studio) UI and via the install.sh to exclude the internal linkage, allowing a developer to simply link any openssl compatible library (including an external wolfssl). The internal ssl is fully configured and tested, but by linking it externally full control is handed over. This solves the non-trivial problem of making ssl easy as well as flexible..c files, as the header are directly included in bulk from the unit test drivers. If I dropped or modified the test drivers we could probably drop at least another 100 .h files. But with the source file removed the headers are not of much consequence unless compiling the tests, since these extras aren't referenced otherwise. So I'm opting for non-modification over compactness, as that preserves upgrade simplicity.tls over tcp (for electrum/stratum-v1 json-rpc), http (bitcoind json-rpc, rest, admin web, rest API), and websockets (fully implemented but currently not used).
The remaining work is all connecting the dots between configuration, construction/retention of the ssl context for a given endpoint, and passage of the context via session->acceptor for accept, and acceptor->socket upon tcp connect (at socket construct). Nothing complicated here, so expect to have this all hooked up tomorrow, and be able to start configuring and testing it.
The implementation is able to support packet level privacy, server auth, and client auth, based on context config for a given endpoint, with independent context for each endpoint. It will also support secure and non-secure endpoints for the same service, if enabled by configuration.
Finally, the socket can accept other types of configuration context (variant), and other types of socket streams (also variant), so this will allow drop-in support for zmq::context and p2p::context security. And of course we will need stream types for zmq to implement that framing, as well as for stratum-v2. But now the implementation will allow these to drop right in to config, context, stream, and security.[explore] connections = 100 bind = 0.0.0.0:80 safe = [::1]:443 safe = [fe80::abd1:6763:de41:21ae]:443 certificate_path = m:/server/certs/server-ecc384-cert.pem key_path = m:/server/certs/server-ecc384-key-enc.pem key_password = libbitcoin
[explore] ... key_password = libbitcoin key_path = m:/server/certs/server-ecc384-key-enc.pem certificate_path = m:/server/certs/server-ecc384-cert.pem certificate_authorities = m:/server/certs
certs>curl -v -k --cert client-ecc384-cert.pem --key client-ecc384-key.pem --cacert ca-ecc384-cert.pem https://localhost:443/v1/top?format=json --verbose Note: Using embedded CA bundle, for proxies (225076 bytes) * Host localhost:443 was resolved. * IPv6: ::1 * IPv4: 127.0.0.1 * Trying [::1]:443... * ALPN: curl offers h2,http/1.1 * TLSv1.3 (OUT), TLS handshake, Client hello (1): * SSL Trust: peer verification disabled * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Unknown (8): * TLSv1.3 (IN), TLS handshake, Request CERT (13): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS handshake, Certificate (11): * TLSv1.3 (OUT), TLS handshake, CERT verify (15): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / [blank] / UNDEF * ALPN: server did not agree on a protocol. Uses default. * Server certificate: * subject: C=US; ST=Washington; L=Seattle; O=Elliptic; OU=ECC384Srv; CN=www.wolfssl.com; emailAddress=info@wolfssl.com * start date: Nov 13 20:41:06 2025 GMT * expire date: Nov 6 20:41:06 2055 GMT * issuer: C=US; ST=Washington; L=Seattle; O=wolfSSL; OU=Development; CN=www.wolfssl.com; emailAddress=info@wolfssl.com * Certificate level 0: Public key type ? (384/192 Bits/secBits), signed using ecdsa-with-SHA384 * SSL certificate verification failed, continuing anyway! * Established connection to localhost (::1 port 443) from ::1 port 54146 * using HTTP/1.x > GET /v1/top?format=json HTTP/1.1 > Host: localhost > User-Agent: curl/8.18.0 > Accept: */* > * Request completely sent off < HTTP/1.1 200 OK < Date: Sun, 25 Jan 2026 04:41:59 GMT < Server: libbitcoin/4 < Keep-Alive: timeout=599 < Content-Type: application/json < Transfer-Encoding: chunked < 900000
wolfssl dependency is optional, as it can alternatively be satisficed with any openssl compatible dependency. We only access it via boost. The total amount of non-config code to implement all of the above TLS features is about 22 lines of code in the socket and 3 lines in the proxy wrapper. We are supporting 5 services with it (web, rest, bitcoind jsonrpc/rest, electrum, stratum-v1), each with independent config. The total to support the implementation is about 50 lines of config code. Adding test modifications and explicit comprehensive tests harnesses for wolfssl, the full implementation across the stack is about 100 lines.TLS over TCP in support of Electrum and Stratum-v1 is now verified (using the Electrum desktop wallet application). No changes required, just some improved logging, source documentation, a couple of localhost self-signed certificates added to ssl/test/vectors.
2026-01-26T04:08:46Z.0 Node is started. 2026-01-26T04:08:46Z.1 Not configured for inbound peer connections. 2026-01-26T04:08:46Z.1 Not configured for outbound connections. 2026-01-26T04:08:46Z.1 Not configured for web connections. 2026-01-26T04:08:46Z.1 Accepting 100 explore connections on 1 clear and 1 private bindings. 2026-01-26T04:08:46Z.1 Bound to private explore endpoint [[::1]:443]. 2026-01-26T04:08:46Z.1 Bound to clear explore endpoint [127.0.0.1:80]. 2026-01-26T04:08:46Z.1 Not configured for bitcoind connections. 2026-01-26T04:08:46Z.1 Accepting 100 electrum connections on 1 clear and 1 private bindings. 2026-01-26T04:08:46Z.1 Bound to private electrum endpoint [0.0.0.0:50002]. 2026-01-26T04:08:46Z.1 Bound to clear electrum endpoint [0.0.0.0:50001]. 2026-01-26T04:08:46Z.1 Not configured for stratum_v1 connections. 2026-01-26T04:08:46Z.1 Not configured for stratum_v2 connections. 2026-01-26T04:08:46Z.0 Node is running. 2026-01-26T04:08:52Z.2 Accepted private electrum connection [127.0.0.1:59800] on binding [0.0.0.0:50002]. 2026-01-26T04:08:53Z.0 Rpc request: [1024] server.version(...). 2026-01-26T04:08:53Z.0 Electrum [127.0.0.1:59800] version (1.4) electrum/4.6.2 2026-01-26T04:08:53Z.0 Rpc response: [60], success. 2026-01-26T04:08:53Z.2 Inbound electrum channel start [127.0.0.1:59800] success(edited)
TLS and clear handshake and connections via Sparrow wallet also verified. A couple of issues were discovered as @eynhaender started putting the client-server e2e test suite together. Also Sparrow ping of our bitcoind endpoint was verified.
Bitcoin Core doesn't support TLS and only provides http basic auth, which is awful and I'd rather not offer it (despite it being trivial to implement). Setting up proper client auth using a self-signed cert is easy. Generating passwords at startup and/or using them over the wire in clear text is 😳.