contrib: remove Bitcoin/upstream-only files, adapt systemd and daemontools to Palladium
Removed: Dockerfile_beefyserver (superseded by the root Dockerfile), sdist/ (upstream release tooling), query.py (broken debug script), raspberrypi3/ (obsolete distro steps and env vars the server now rejects). systemd and daemontools samples now use COIN=Palladium, the node RPC port 2332, DB_ENGINE and SERVICES (both required for a working server). HOWTO.rst drops the Raspberry Pi section. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4295cd01a1
commit
1b537297df
14 files changed
+16
-444
No files matched your search
@@ -1,82 +0,0 @@
|
||||
# ElectrumX for Bitcoin, with RocksDB
|
||||
# This Dockerfile is intended for modern multi-core servers with at least 16 GB of RAM.
|
||||
# We compile our own free-threaded Python, with --disable-gil (which is experimental!), which makes
|
||||
# ElectrumX able to truly utilise multiple CPU cores and makes processing blocks significantly faster.
|
||||
#
|
||||
# Build: docker build -f Dockerfile_beefyserver --pull -t electrumx .
|
||||
# Run: docker run -d --net=host -v ~/electrumx-db:/var/lib/electrumx -e DAEMON_URL="http://youruser:yourpass@localhost:8332" -e REPORT_SERVICES=tcp://example.com:50001 electrumx
|
||||
# Stop: docker stop CONTAINER_ID
|
||||
|
||||
FROM debian:trixie
|
||||
|
||||
ENV LC_ALL=C.UTF-8 LANG=C.UTF-8
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install libs needed to build CPython
|
||||
RUN apt-get update \
|
||||
&& apt-get -y install \
|
||||
git \
|
||||
wget \
|
||||
make \
|
||||
autotools-dev \
|
||||
autoconf \
|
||||
libtool \
|
||||
xz-utils \
|
||||
libssl-dev \
|
||||
libssl3 \
|
||||
openssl \
|
||||
zlib1g-dev \
|
||||
libffi-dev \
|
||||
libncurses5-dev \
|
||||
libsqlite3-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install libs needed to build RocksDB
|
||||
RUN apt-get update \
|
||||
&& apt-get -y --no-install-recommends install \
|
||||
build-essential \
|
||||
git \
|
||||
librocksdb-dev \
|
||||
pkg-config \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# build CPython (free-threaded, with --disable-gil)
|
||||
ARG PYTHON_VERSION="v3.14.6"
|
||||
RUN cd /opt && \
|
||||
git clone https://github.com/python/cpython && \
|
||||
cd cpython/ && \
|
||||
git checkout "${PYTHON_VERSION}" && \
|
||||
./configure \
|
||||
--prefix="/usr" \
|
||||
--enable-ipv6 \
|
||||
--enable-shared \
|
||||
--disable-gil \
|
||||
-q && \
|
||||
make -s "-j$(nproc)" && \
|
||||
make install
|
||||
|
||||
RUN python3 -m pip install --upgrade pip setuptools wheel
|
||||
|
||||
# Install ElectrumX
|
||||
ARG ELECTRUMX_VERSION=2.0.0
|
||||
#ARG ELECTRUMX_VERSION=b8f6e227f251fe5cba96b940ffaa094439636417
|
||||
RUN python3 -m pip install \
|
||||
"e_x[rocksdb] @ git+https://github.com/spesmilo/electrumx.git@${ELECTRUMX_VERSION}"
|
||||
|
||||
|
||||
ENV SERVICES="tcp://:50001"
|
||||
ENV COIN=Bitcoin
|
||||
ENV DB_DIRECTORY=/var/lib/electrumx
|
||||
ENV DAEMON_URL="http://username:password@hostname:port/"
|
||||
ENV ALLOW_ROOT=true
|
||||
ENV DB_ENGINE=rocksdb
|
||||
ENV CACHE_MB=2000
|
||||
|
||||
|
||||
VOLUME /var/lib/electrumx
|
||||
|
||||
RUN mkdir -p "$DB_DIRECTORY"
|
||||
|
||||
CMD ["electrumx_server"]
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
Bitcoin
|
||||
Palladium
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
http://username:password@host:port/
|
||||
http://username:password@127.0.0.1:2332/
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
rocksdb
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
tcp://:50001,rpc://
|
||||
@@ -1,111 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2016-2018, Neil Booth
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# See the file "LICENCE" for information about the copyright
|
||||
# and warranty status of this software.
|
||||
|
||||
'''Script to query the database for debugging purposes.
|
||||
|
||||
Not currently documented; might become easier to use in future.
|
||||
'''
|
||||
|
||||
import argparse
|
||||
import asyncio
|
||||
|
||||
from electrumx import Env
|
||||
from electrumx.server.db import DB
|
||||
from electrumx.lib.hash import hash_to_hex_str, Base58Error
|
||||
|
||||
|
||||
async def print_stats(hist_db, utxo_db):
|
||||
count = 0
|
||||
for key in utxo_db.iterator(prefix=b'u', include_value=False):
|
||||
count += 1
|
||||
print(f'UTXO count: {utxos}')
|
||||
|
||||
count = 0
|
||||
for key in utxo_db.iterator(prefix=b'h', include_value=False):
|
||||
count += 1
|
||||
print(f'HashX count: {count}')
|
||||
|
||||
hist = 0
|
||||
hist_len = 0
|
||||
for key, value in hist_db.iterator(prefix=b'H'):
|
||||
hist += 1
|
||||
hist_len += len(value) // 4
|
||||
print(f'History rows {hist:,d} entries {hist_len:,d}')
|
||||
|
||||
|
||||
def arg_to_hashX(coin, arg):
|
||||
try:
|
||||
script = bytes.fromhex(arg)
|
||||
print(f'Script: {arg}')
|
||||
return coin.hashX_from_script(script)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
try:
|
||||
hashX = coin.address_to_hashX(arg)
|
||||
print(f'Address: {arg}')
|
||||
return hashX
|
||||
except Base58Error:
|
||||
print(f'Ingoring unknown arg: {arg}')
|
||||
return None
|
||||
|
||||
|
||||
async def query(args):
|
||||
env = Env()
|
||||
db = DB(env)
|
||||
coin = env.coin
|
||||
|
||||
await db.open_for_serving()
|
||||
|
||||
if not args.scripts:
|
||||
await print_stats(db.hist_db, db.utxo_db)
|
||||
return
|
||||
limit = args.limit
|
||||
for arg in args.scripts:
|
||||
hashX = arg_to_hashX(coin, arg)
|
||||
if not hashX:
|
||||
continue
|
||||
n = None
|
||||
history = await db.limited_history(hashX, limit=limit)
|
||||
for n, (tx_hash, height) in enumerate(history, start=1):
|
||||
print(f'History #{n:,d}: height {height:,d} '
|
||||
f'tx_hash {hash_to_hex_str(tx_hash)}')
|
||||
if n is None:
|
||||
print('No history found')
|
||||
n = None
|
||||
utxos = await db.all_utxos(hashX)
|
||||
for n, utxo in enumerate(utxos, start=1):
|
||||
print(f'UTXO #{n:,d}: tx_hash {hash_to_hex_str(utxo.txid_rev)} '
|
||||
f'tx_pos {utxo.tx_pos:,d} height {utxo.height:,d} '
|
||||
f'value {utxo.value:,d}')
|
||||
if n == limit:
|
||||
break
|
||||
if n is None:
|
||||
print('No UTXOs found')
|
||||
balance = sum(utxo.value for utxo in utxos)
|
||||
print(f'Balance: {coin.decimal_value(balance):,f} {coin.SHORTNAME}')
|
||||
|
||||
|
||||
def main():
|
||||
default_limit = 10
|
||||
parser = argparse.ArgumentParser(
|
||||
'query.py',
|
||||
description='Invoke with COIN and DB_DIRECTORY set in the '
|
||||
'environment as they would be invoking electrumx_server'
|
||||
)
|
||||
parser.add_argument('-l', '--limit', metavar='limit', type=int,
|
||||
default=10, help=f'maximum number of entries to '
|
||||
f'return (default: {default_limit})')
|
||||
parser.add_argument('scripts', nargs='*', default=[], type=str,
|
||||
help='hex scripts to query')
|
||||
args = parser.parse_args()
|
||||
asyncio.run(query(args))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
###################
|
||||
# install electrumx
|
||||
###################
|
||||
|
||||
# Remove "raspi-copies-and-fills" as it breaks the upgrade process
|
||||
sudo apt-get purge raspi-copies-and-fills
|
||||
|
||||
# upgrade raspbian to 'stretch' distribution
|
||||
sudo echo 'deb http://mirrordirector.raspbian.org/raspbian/ testing main contrib non-free rpi' > /etc/apt/sources.list.d/stretch.list
|
||||
sudo apt-get update
|
||||
sudo apt-get dist-upgrade
|
||||
sudo apt-get autoremove
|
||||
|
||||
# install electrumx dependencies
|
||||
sudo apt-get install python3-pip
|
||||
sudo apt-get install build-essential libc6-dev
|
||||
sudo apt-get install libncurses5-dev libncursesw5-dev
|
||||
sudo apt install libreadline6-dev/stable libreadline6/stable
|
||||
sudo apt-get install libleveldb-dev
|
||||
sudo apt-get install git
|
||||
sudo pip3 install plyvel
|
||||
|
||||
# install electrumx
|
||||
git clone https://github.com/spesmilo/electrumx.git
|
||||
cd electrumx
|
||||
sudo python3 -m pip install .
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/bin/sh
|
||||
###############
|
||||
# run_electrumx
|
||||
###############
|
||||
|
||||
# configure electrumx
|
||||
export COIN=Bitcoin
|
||||
export DAEMON_URL=http://rpcuser:rpcpassword@127.0.0.1
|
||||
export NET=mainnet
|
||||
export CACHE_MB=400
|
||||
export DB_DIRECTORY=/home/username/.electrumx/db
|
||||
export SSL_CERTFILE=/home/username/.electrumx/certfile.crt
|
||||
export SSL_KEYFILE=/home/username/.electrumx/keyfile.key
|
||||
export BANNER_FILE=/home/username/.electrumx/banner
|
||||
export DONATION_ADDRESS=your-donation-address
|
||||
|
||||
# connectivity
|
||||
export HOST=
|
||||
export TCP_PORT=50001
|
||||
export SSL_PORT=50002
|
||||
|
||||
# visibility
|
||||
export REPORT_HOST=hostname.com
|
||||
export RPC_PORT=8000
|
||||
|
||||
# run electrumx
|
||||
ulimit -n 10000
|
||||
/usr/local/bin/electrumx_server 2>> /home/username/.electrumx/electrumx.log >> /home/username/.electrumx/electrumx.log &
|
||||
|
||||
######################
|
||||
# auto-start electrumx
|
||||
######################
|
||||
|
||||
# add this line to crontab -e
|
||||
# @reboot /path/to/run_electrumx.sh
|
||||
@@ -1,30 +0,0 @@
|
||||
FROM debian:bookworm@sha256:b877a1a3fdf02469440f1768cf69c9771338a875b7add5e80c45b756c92ac20a
|
||||
|
||||
ENV LC_ALL=C.UTF-8 LANG=C.UTF-8
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update -q && \
|
||||
apt-get install -qy \
|
||||
git \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-setuptools \
|
||||
python3-venv \
|
||||
python3-build \
|
||||
&& \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
apt-get autoremove -y && \
|
||||
apt-get clean
|
||||
|
||||
# create new user to avoid using root; but with sudo access and no password for convenience.
|
||||
ARG UID=1000
|
||||
ENV USER="user"
|
||||
ENV HOME_DIR="/home/${USER}"
|
||||
ENV WORK_DIR="${HOME_DIR}/wspace" \
|
||||
PATH="${HOME_DIR}/.local/bin:${PATH}"
|
||||
RUN useradd --uid $UID --create-home --shell /bin/bash ${USER}
|
||||
RUN usermod -append --groups sudo ${USER}
|
||||
RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||
WORKDIR ${WORK_DIR}
|
||||
RUN chown --recursive ${USER} ${WORK_DIR}
|
||||
USER ${USER}
|
||||
@@ -1,29 +0,0 @@
|
||||
# Source tarballs
|
||||
|
||||
✓ _These tarballs should be reproducible, meaning you should be able to generate
|
||||
distributables that match the official releases._
|
||||
|
||||
This assumes an Ubuntu (x86_64) host, but it should not be too hard to adapt to another
|
||||
similar system.
|
||||
|
||||
|
||||
## Build steps
|
||||
|
||||
1. Install Docker
|
||||
|
||||
See [`docker_notes.md`](https://github.com/spesmilo/electrum/blob/master/contrib/docker_notes.md).
|
||||
|
||||
(worth reading even if you already have docker)
|
||||
|
||||
2. Build tarball
|
||||
|
||||
```
|
||||
$ ./contrib/sdist/build.sh
|
||||
```
|
||||
If you want reproducibility, try instead e.g.:
|
||||
```
|
||||
$ ELECBUILD_COMMIT=HEAD ELECBUILD_NOCACHE=1 ./contrib/sdist/build.sh
|
||||
```
|
||||
|
||||
3. The generated distributables are in `./dist`.
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# env vars:
|
||||
# - ELECBUILD_NOCACHE: if set, forces rebuild of docker image
|
||||
# - ELECBUILD_COMMIT: if set, do a fresh clone and git checkout
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_ROOT="$(dirname "$(readlink -e "$0")")/../.."
|
||||
PROJECT_ROOT_OR_FRESHCLONE_ROOT="$PROJECT_ROOT"
|
||||
CONTRIB="$PROJECT_ROOT/contrib"
|
||||
CONTRIB_SDIST="$CONTRIB/sdist"
|
||||
DISTDIR="$PROJECT_ROOT/dist"
|
||||
BUILD_UID=$(/usr/bin/stat -c %u "$PROJECT_ROOT")
|
||||
|
||||
export SOURCE_DATE_EPOCH=1530212462
|
||||
export PYTHONHASHSEED=22
|
||||
|
||||
|
||||
DOCKER_BUILD_FLAGS=""
|
||||
if [ ! -z "$ELECBUILD_NOCACHE" ] ; then
|
||||
echo "ELECBUILD_NOCACHE is set. forcing rebuild of docker image."
|
||||
DOCKER_BUILD_FLAGS="--pull --no-cache"
|
||||
fi
|
||||
|
||||
if [ -z "$ELECBUILD_COMMIT" ] ; then # local dev build
|
||||
DOCKER_BUILD_FLAGS="$DOCKER_BUILD_FLAGS --build-arg UID=$BUILD_UID"
|
||||
fi
|
||||
|
||||
echo "building docker image."
|
||||
docker build \
|
||||
$DOCKER_BUILD_FLAGS \
|
||||
-t electrumx-builder-img \
|
||||
"$CONTRIB_SDIST"
|
||||
|
||||
# maybe do fresh clone
|
||||
if [ ! -z "$ELECBUILD_COMMIT" ] ; then
|
||||
echo "ELECBUILD_COMMIT=$ELECBUILD_COMMIT. doing fresh clone and git checkout."
|
||||
FRESH_CLONE="/tmp/electrumx_build/fresh_clone/electrumx"
|
||||
rm -rf "$FRESH_CLONE" 2>/dev/null || ( echo "we need sudo to rm prev FRESH_CLONE." && sudo rm -rf "$FRESH_CLONE" )
|
||||
umask 0022
|
||||
git clone "$PROJECT_ROOT" "$FRESH_CLONE"
|
||||
cd "$FRESH_CLONE"
|
||||
git checkout "$ELECBUILD_COMMIT"
|
||||
PROJECT_ROOT_OR_FRESHCLONE_ROOT="$FRESH_CLONE"
|
||||
else
|
||||
echo "not doing fresh clone."
|
||||
fi
|
||||
|
||||
echo "building binary..."
|
||||
# check uid and maybe chown. see #8261
|
||||
if [ ! -z "$ELECBUILD_COMMIT" ] ; then # fresh clone (reproducible build)
|
||||
if [ $(id -u) != "1000" ] || [ $(id -g) != "1000" ] ; then
|
||||
echo "need to chown -R FRESH_CLONE dir. prompting for sudo."
|
||||
sudo chown -R 1000:1000 "$FRESH_CLONE"
|
||||
fi
|
||||
fi
|
||||
docker run -it \
|
||||
--name electrumx-builder-cont \
|
||||
-v "$PROJECT_ROOT_OR_FRESHCLONE_ROOT":/opt/electrumx \
|
||||
--rm \
|
||||
--workdir /opt/electrumx/contrib/sdist \
|
||||
electrumx-builder-img \
|
||||
./make_sdist.sh
|
||||
|
||||
# make sure resulting binary location is independent of fresh_clone
|
||||
if [ ! -z "$ELECBUILD_COMMIT" ] ; then
|
||||
mkdir --parents "$DISTDIR/"
|
||||
cp -f "$FRESH_CLONE/dist"/* "$DISTDIR/"
|
||||
fi
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_ROOT="$(dirname "$(readlink -e "$0")")/../.."
|
||||
CONTRIB="$PROJECT_ROOT/contrib"
|
||||
CONTRIB_SDIST="$CONTRIB/sdist"
|
||||
BUILDDIR="$CONTRIB_SDIST/build"
|
||||
DISTDIR="$PROJECT_ROOT/dist"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
rm -rf "$BUILDDIR"
|
||||
mkdir -p "$BUILDDIR" "$DISTDIR"
|
||||
|
||||
|
||||
git_status=$(git status --porcelain)
|
||||
if [ ! -z "$git_status" ]; then
|
||||
echo "$git_status"
|
||||
echo "git repo not clean, aborting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
python3 -m build --sdist . --outdir "$BUILDDIR/dist1"
|
||||
|
||||
|
||||
# the initial tar.gz is not reproducible, see https://github.com/pypa/setuptools/issues/2133
|
||||
# so we untar, fix timestamps, and then re-tar
|
||||
DISTNAME=$(find "$BUILDDIR/dist1/" -type f -name 'e_x-*.tar.gz' -printf "%f\\n")
|
||||
DIST_BASENAME=$(basename --suffix ".tar.gz" "$DISTNAME")
|
||||
mkdir -p "$BUILDDIR/dist2"
|
||||
cd "$BUILDDIR/dist2"
|
||||
tar -xzf "$BUILDDIR/dist1/$DISTNAME"
|
||||
find -exec touch -h -d '2000-11-11T11:11:11+00:00' {} +
|
||||
GZIP=-n tar --sort=name -czf "$DISTNAME" "$DIST_BASENAME/"
|
||||
mv "$DISTNAME" "$DISTDIR/$DISTNAME"
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
# default /etc/electrumx.conf for systemd
|
||||
# default /etc/electrumx.conf for systemd (plm-electrumx, Palladium)
|
||||
|
||||
# REQUIRED
|
||||
DB_DIRECTORY = /db
|
||||
# Bitcoin Node RPC Credentials
|
||||
DAEMON_URL = http://username:password@hostname:port/
|
||||
# leveldb or rocksdb (the matching pip extra must be installed)
|
||||
DB_ENGINE = rocksdb
|
||||
# Palladium node RPC credentials (the node needs server=1 and txindex=1)
|
||||
DAEMON_URL = http://username:password@127.0.0.1:2332/
|
||||
# without SERVICES the server accepts no connections. rpc:// is needed by electrumx_rpc (used by the service file to stop)
|
||||
SERVICES = tcp://:50001,rpc://
|
||||
|
||||
# COIN = Bitcoin
|
||||
# Palladium is the default coin; NET can be mainnet (default), testnet or regtest
|
||||
# COIN = Palladium
|
||||
# NET = mainnet
|
||||
|
||||
# See https://electrumx-spesmilo.readthedocs.io/en/latest/environment.html for
|
||||
# information about other configuration settings you probably want to consider.
|
||||
# See docs/environment.rst for information about other configuration settings
|
||||
# you probably want to consider (SSL_CERTFILE/SSL_KEYFILE and ssl:// in SERVICES, REPORT_SERVICES, ...).
|
||||
@@ -234,17 +234,6 @@ Once configured you may want to start ElectrumX at boot::
|
||||
:file:`.service` file.
|
||||
|
||||
|
||||
Installing on Raspberry Pi 3
|
||||
----------------------------
|
||||
|
||||
To install on the Raspberry Pi 3 you will need to update to the
|
||||
``stretch`` distribution. See the full procedure in
|
||||
`contrib/raspberrypi3/install_electrumx.sh`_.
|
||||
|
||||
See also `contrib/raspberrypi3/run_electrumx.sh`_ for an easy way to
|
||||
configure and launch electrumx.
|
||||
|
||||
|
||||
Sync Progress
|
||||
=============
|
||||
|
||||
@@ -451,5 +440,3 @@ You can then set the port as follows and advertise the service externally on the
|
||||
.. _`daemontools`: http://cr.yp.to/daemontools.html
|
||||
.. _`runit`: http://smarden.org/runit/index.html
|
||||
.. _`aiohttp`: https://pypi.python.org/pypi/aiohttp
|
||||
.. _`contrib/raspberrypi3/install_electrumx.sh`: https://github.com/spesmilo/electrumx/blob/master/contrib/raspberrypi3/install_electrumx.sh
|
||||
.. _`contrib/raspberrypi3/run_electrumx.sh`: https://github.com/spesmilo/electrumx/blob/master/contrib/raspberrypi3/run_electrumx.sh
|
||||
Reference in new issue
Block a user