electrs
electrs is an Electrum Server implementation in Rust, with the project information and source code available on GitHub (romanz/electrs). It uses Bitcoin Core as a data source and builds its own set of indexes to server Bitcoin transaction data to Electrum clients, like our BitBoxApp.
Building from source or pre-compiled binary
The electrs project does not provide official binary releases. Because compiling from source during the Armbian build fails due to timeouts, a precompiled .deb package is used. This is a temporary solution and we’d like to address that and contribute to a solution over time.
Configuration
The application configuration is specified in the local /etc/electrs/electrs.conf
file. Please check the most current initial configuration in customize-armbian-rockpro64.sh
.
NETWORK=mainnet
RPCCONNECT=127.0.0.1
RPCPORT=8332
DB_DIR=/mnt/ssd/electrs/db
DAEMON_DIR=/mnt/ssd/bitcoin/.bitcoin
MONITORING_ADDR=127.0.0.1:4224
VERBOSITY=vvvv
RUST_BACKTRACE=1
RPCUSER=base
RPCPASSWORD=HnRzxTcTKhVfMqKv0qk4h-WeaJLSKJkAFOr9Szr2F4s=
Contrary to other applications, this config file defines environment variables that are passed to electrs as commandline arguments.
Additional information about commandline arguments can be found by running electrs --help
:
Electrum Rust Server 0.7.0
USAGE:
electrs [FLAGS] [OPTIONS]
FLAGS:
-h, --help Prints help information
--jsonrpc-import Use JSONRPC instead of directly importing blk*.dat files. Useful for remote full node or low
memory system
--timestamp Prepend log lines with a timestamp
-V, --version Prints version information
-v Increase logging verbosity
OPTIONS:
--bulk-index-threads <bulk_index_threads>
Number of threads used for bulk indexing (default: use the # of CPUs) [default: 0]
--cookie <cookie>
JSONRPC authentication cookie ('USER:PASSWORD', default: read from ~/.bitcoin/.cookie)
--daemon-dir <daemon_dir> Data directory of Bitcoind (default: ~/.bitcoin/)
--daemon-rpc-addr <daemon_rpc_addr>
Bitcoin daemon JSONRPC 'addr:port' to connect (default: 127.0.0.1:8332 for mainnet, 127.0.0.1:18332 for
testnet and 127.0.0.1:18443 for regtest)
--db-dir <db_dir> Directory to store index database (default: ./db/)
--electrum-rpc-addr <electrum_rpc_addr>
Electrum server JSONRPC 'addr:port' to listen on (default: '127.0.0.1:50001' for mainnet, '127.0.0.1:60001'
for testnet and '127.0.0.1:60401' for regtest)
--index-batch-size <index_batch_size>
Number of blocks to get in one JSONRPC request from bitcoind [default: 100]
--monitoring-addr <monitoring_addr>
Prometheus monitoring 'addr:port' to listen on (default: 127.0.0.1:4224 for mainnet, 127.0.0.1:14224 for
testnet and 127.0.0.1:24224 for regtest)
--network <network> Select Bitcoin network type ('mainnet', 'testnet' or 'regtest')
--server-banner <server_banner>
The banner to be shown in the Electrum console [default: Welcome to electrs 0.7.0 (Electrum Rust Server)!]
--tx-cache-size <tx_cache_size>
Number of transactions to keep in for query LRU cache [default: 10000]
--txid-limit <txid_limit>
Number of transactions to lookup before returning an error, to prevent "too popular" addresses from causing
the RPC server to get stuck (0 - disable the limit) [default: 100]
Service management
The bitcoind service is managed by systemd. Relevant parameters are specified in the unit file electrs.service
shown below. Please check the most current initial configuration in customize-armbian-rockpro64.sh
.
[Unit]
Description=Electrs server daemon
After=multi-user.target bitcoind.service
[Service]
# Service execution
###################
EnvironmentFile=/etc/electrs/electrs.conf
ExecStartPre=+/opt/shift/scripts/systemd-electrs-startpre.sh
ExecStart=/usr/bin/electrs \
--network ${NETWORK} \
--db-dir ${DB_DIR} \
--daemon-dir ${DAEMON_DIR} \
--cookie "${RPCUSER}:${RPCPASSWORD}" \
--monitoring-addr ${MONITORING_ADDR} \
-${VERBOSITY}
# Process management
####################
Type=simple
Restart=always
TimeoutSec=120
RestartSec=30
KillMode=process
# Directory creation and permissions
####################################
# Run as electrs:bitcoin
User=electrs
Group=bitcoin
# /run/electrs
RuntimeDirectory=electrs
RuntimeDirectoryMode=0710
# Hardening measures
####################
# Provide a private /tmp and /var/tmp.
PrivateTmp=true
# Mount /usr, /boot/ and /etc read-only for the process.
ProtectSystem=full
# Deny access to /home, /root and /run/user
ProtectHome=true
# Disallow the process and all of its children to gain
# new privileges through execve().
NoNewPrivileges=true
# Use a new /dev namespace only populated with API pseudo devices
# such as /dev/null, /dev/zero and /dev/random.
PrivateDevices=true
# Deny the creation of writable and executable memory mappings.
MemoryDenyWriteExecute=true
[Install]
WantedBy=bitboxbase.target
Some notes about this specific configuration:
After
: started after bitcoindExecStartPre
: runssystemd-electrs-startpre.sh
to check dependenciesUser
: runs as service user “electrs”Group
: use group “bitcoin” to have access to the relevant bitcoind directoriesRestart
: always restarted, unless manually stoppedPrivateTmp
: using a private tmp directoryProtectSystem
: mount /usr, /boot/ and /etc read-only for the processNoNewPrivileges
: disallow the process and all of its children to gain new privileges through execve()PrivateDevices
: use a new /dev namespace only populated with API pseudo devices such as /dev/null, /dev/zero and /dev/randomMemoryDenyWriteExecute
: deny the creation of writable and executable memory mappings
Starting electrs
The systemd unit executes electrs with the shell script systemd-electrs-startpre.sh
. This allows the execution of additional commands for preparation and post-processing.
For additional details, please check the inline comments directly in the script.
Data storage
The additional indexes are stored on the SSD due to their significant size. The storage location /mnt/ssd/electrs/db
is specified in the electrs.conf
file.