From daab197a0116bbe5508911e83adda504fad357c6 Mon Sep 17 00:00:00 2001 From: dan-s Date: Wed, 4 Mar 2026 15:28:02 -0600 Subject: [PATCH] update for dragonx binary changes, added monitor script --- Makefile | 9 +-- README.md | 59 ++++++++------------ cmd/server/main.go | 34 ++++++------ common/common.go | 8 +-- frontend/rpc_client.go | 6 +- frontend/service.go | 12 ++-- monitor_lwd.sh | 123 +++++++++++++++++++++++++++++++++++++++++ util/build.sh | 4 +- 8 files changed, 184 insertions(+), 71 deletions(-) create mode 100755 monitor_lwd.sh diff --git a/Makefile b/Makefile index d2a920d..5eae103 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ # Copyright (c) 2021 Jahway603 & The Hush Developers +# Copyright (c) 2024-2026 The DragonX Developers # Released under the GPLv3 # -# Hush Lightwalletd Makefile +# DragonX Lightwalletd Makefile # author: jahway603 # PROJECT_NAME := "lightwalletd" @@ -19,9 +20,9 @@ build-arm: # Build binary for ARM architecture (aarch64) ./util/build_arm.sh -# Stop the hushd process in the hushdlwd container -#docker_img_stop_hushd: -# docker exec -i hushdlwd hush-cli stop +# Stop the dragonxd process in the container +#docker_img_stop_dragonxd: +# docker exec -i dragonxdlwd dragonx-cli stop # Remove and delete ALL images and containers in Docker; assumes containers are stopped #docker_remove_all: diff --git a/README.md b/README.md index b8cda6c..fbfa632 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,20 @@ # Overview -Hush Lightwalletd is a fork of [lightwalletd](https://github.com/adityapk00/lightwalletd) original from Zcash (ZEC). +DragonX Lightwalletd is a fork of [Hush lightwalletd](https://git.hush.is/hush/lightwalletd) which is itself a fork of [lightwalletd](https://github.com/adityapk00/lightwalletd) originally from Zcash (ZEC). -It is a backend service that provides a bandwidth-efficient interface to the Hush blockchain for [SilentDragonLite cli](https://git.hush.is/hush/silentdragonlite-light-cli) and [SilentDragonLite](https://git.hush.is/hush/SilentDragonLite). +It is a backend service that provides a bandwidth-efficient interface to the DragonX blockchain for light wallet clients. -## Changes from upstream lightwalletd -This version of lightwalletd extends lightwalletd and: +## Features -* Adds support for HUSH -* Adds support for transparent addresses -* Adds several new RPC calls for lightclients +* Support for DragonX (standalone chain with `dragonxd`) +* Support for transparent addresses +* Several RPC calls for light clients * Lots of perf improvements - * Replaces SQLite with in-memory cache for Compact Blocks - * Replace local Txstore, delegating Tx lookups to hushd - * Remove the need for a separate ingestor + * In-memory cache for Compact Blocks (replaces SQLite) + * Tx lookups delegated to dragonxd + * No separate ingestor needed -## Running your own SDL lightwalletd +## Running your own DragonX lightwalletd #### 0. First, install Go You will need Go >= 1.13 which you can download from the official [download page](https://golang.org/dl/) or install via your OS package manager. @@ -28,15 +27,15 @@ If you're using Ubuntu or Debian, try: $ sudo apt install golang ``` -#### 1. Run a Hush node. -Either compile or build the [Hush Daemon (hushd)](https://git.hush.is/hush/hush3). +#### 1. Run a DragonX node. +Install the DragonX daemon (`dragonxd`) and CLI (`dragonx-cli`). -Next, change your HUSH3.conf file to something like the following: +Next, ensure your DRAGONX.conf file (at `~/.hush/DRAGONX/DRAGONX.conf`) has something like the following: ``` rpcuser=user-CHANGETHIS rpcpassword=pass-CHANGETHIS -rpcport=18031 +rpcport=21769 server=1 txindex=1 rpcworkqueue=256 @@ -44,7 +43,7 @@ rpcallowip=127.0.0.1 rpcbind=127.0.0.1 ``` -Then start `hushd` in your command window. You might need to run with `-reindex` the first time if you are enabling the `txindex` or `insightexplorer` options for the first time. The reindex might take a while. +Then start `dragonxd`. You might need to run with `-reindex` the first time if you are enabling the `txindex` option for the first time. The reindex might take a while. #### 2. Compile lightwalletd Run the build script. @@ -77,9 +76,8 @@ server { ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot location / { - # Replace localhost:9067 with the address and port of your gRPC server if using a custom port - # Hush Smart Chains should use a different port than 9067 so it doesn't conflict with HUSH lightwalletd - grpc_pass grpc://your_host.net:9067; + # Replace localhost:9069 with the address and port of your gRPC server if using a custom port + grpc_pass grpc://your_host.net:9069; } } ``` @@ -87,28 +85,18 @@ server { Then run the lightwalletd frontend with the following (Note: we use the "-no-tls" option as we are using NGINX as a reverse proxy and letting it handle the TLS authentication for us instead): ``` -./lightwalletd -bind-addr your_host.net:9067 -conf-file ~/.hush/HUSH3/HUSH3.conf -no-tls +./lightwalletd -bind-addr your_host.net:9069 -conf-file ~/.hush/DRAGONX/DRAGONX.conf -no-tls ``` ##### Option B: "Let's Encrypt" certificate just using lightwalletd without NGINX The other option is to configure lightwalletd to handle its own TLS authentication. Once you have a certificate that you want to use (from a certificate authority), pass the certificate to the frontend as follows: ``` -./lightwalletd -bind-addr 127.0.0.1:9067 -conf-file ~/.hush/HUSH3/HUSH3.conf -tls-cert /etc/letsencrypt/live/YOURWEBSITE/fullchain.pem -tls-key /etc/letsencrypt/live/YOURWEBSITE/privkey.pem +./lightwalletd -bind-addr 127.0.0.1:9069 -conf-file ~/.hush/DRAGONX/DRAGONX.conf -tls-cert /etc/letsencrypt/live/YOURWEBSITE/fullchain.pem -tls-key /etc/letsencrypt/live/YOURWEBSITE/privkey.pem ``` -#### 4. Point the `silentdragonlite-cli` to this server -You should start seeing the frontend ingest and cache the Hush blocks after ~15 seconds. - -Now, connect to your server! (Substitute with your own below) -``` -git clone https://git.hush.is/hush/silentdragonlite-cli -cd silentdragonlite-cli -cargo build --release -./target/release/silentdragonlite-cli --server https://lite.example.org -``` - -* If you have trouble compiling silentdragonlite-cli, then [please refer to it's separate documentation here](https://git.hush.is/hush/silentdragonlite-cli) on how to build it and what pre-requisites need to be installed. +#### 4. Point a light wallet client to this server +You should start seeing the frontend ingest and cache the DragonX blocks after ~15 seconds. ## Lightwalletd Command-line Options @@ -116,7 +104,7 @@ These are the current different command line options for lightwalletd: | CLI option | Default | What it does | |------------|:--------------:|------------------------------:| -| -bind-addr | 127.0.0.1:9067 | address and port to listen on | +| -bind-addr | 127.0.0.1:9069 | address and port to listen on | | -tls-cert | blank | the path to a TLS certificate | | -tls-key | blank | the path to a TLS key file | | -no-tls | false | Disable TLS, serve un-encrypted traffic | @@ -126,7 +114,7 @@ These are the current different command line options for lightwalletd: | -cache-size| 40000 | number of blocks to hold in the cache | ## Support -For support or other questions, join us on [Telegram](https://hush.is/telegram), or tweet at [@HushIsPrivacy](https://twitter.com/HushIsPrivacy), or toot at our [Mastodon](https://fosstodon.org/@myhushteam) or join [Telegram Support](https://hush.is/telegram_support). +For support or other questions, join us on [Telegram](https://hush.is/telegram) or join [Telegram Support](https://hush.is/telegram_support). ## License GPLv3 or later @@ -134,3 +122,4 @@ GPLv3 or later # Copyright 2016-2022 The Hush Developers +2024-2026 The DragonX Developers diff --git a/cmd/server/main.go b/cmd/server/main.go index 209c267..b51776f 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -77,32 +77,32 @@ func loggerFromContext(ctx context.Context) *logrus.Entry { } type Options struct { - bindAddr string `json:"bind_address,omitempty"` - tlsCertPath string `json:"tls_cert_path,omitempty"` - tlsKeyPath string `json:"tls_cert_key,omitempty"` - noTLS bool `json:no_tls,omitempty` - logLevel uint64 `json:"log_level,omitempty"` - logPath string `json:"log_file,omitempty"` - hush3ConfPath string `json:"hush3_conf,omitempty"` - cacheSize int `json:"hush3_conf,omitempty"` + bindAddr string `json:"bind_address,omitempty"` + tlsCertPath string `json:"tls_cert_path,omitempty"` + tlsKeyPath string `json:"tls_cert_key,omitempty"` + noTLS bool `json:no_tls,omitempty` + logLevel uint64 `json:"log_level,omitempty"` + logPath string `json:"log_file,omitempty"` + confPath string `json:"conf_file,omitempty"` + cacheSize int `json:"cache_size,omitempty"` } func main() { var version = "0.1.1" // set version number opts := &Options{} - flag.StringVar(&opts.bindAddr, "bind-addr", "127.0.0.1:9067", "the address to listen on") + flag.StringVar(&opts.bindAddr, "bind-addr", "127.0.0.1:9069", "the address to listen on") flag.StringVar(&opts.tlsCertPath, "tls-cert", "", "the path to a TLS certificate (optional)") flag.StringVar(&opts.tlsKeyPath, "tls-key", "", "the path to a TLS key file (optional)") flag.BoolVar(&opts.noTLS, "no-tls", false, "Disable TLS, serve un-encrypted traffic.") flag.Uint64Var(&opts.logLevel, "log-level", uint64(logrus.InfoLevel), "log level (logrus 1-7)") flag.StringVar(&opts.logPath, "log-file", "", "log file to write to") - flag.StringVar(&opts.hush3ConfPath, "conf-file", "", "conf file to pull RPC creds from") + flag.StringVar(&opts.confPath, "conf-file", "", "conf file to pull RPC creds from") flag.IntVar(&opts.cacheSize, "cache-size", 40000, "number of blocks to hold in the cache") // creating --version as a requirement of help2man if len(os.Args) > 1 && (os.Args[1] == "--version" || os.Args[1] == "-v") { - fmt.Printf("Hush lightwalletd version " + version + "\n") + fmt.Printf("DragonX lightwalletd version " + version + "\n") os.Exit(0) } @@ -110,14 +110,14 @@ func main() { // TODO support config from file and env vars flag.Parse() - if opts.hush3ConfPath == "" { + if opts.confPath == "" { flag.Usage() os.Exit(1) } if !opts.noTLS && (opts.tlsCertPath == "" || opts.tlsKeyPath == "") { println("Please specify a TLS certificate/key to use. You can use a self-signed certificate.") - println("See https://git.hush.is/hush/lightwalletd/src/branch/master/README.md#running-your-own-sdl-lightwalletd") + println("See https://git.hush.is/hush/lightwalletd/src/branch/master/README.md") os.Exit(1) } @@ -159,17 +159,17 @@ func main() { reflection.Register(server) } - // Initialize Hush RPC client. Right now (Jan 2018) this is only for + // Initialize DragonX RPC client. Right now this is only for // sending transactions, but in the future it could back a different type // of block streamer. - rpcClient, err := frontend.NewZRPCFromConf(opts.hush3ConfPath) + rpcClient, err := frontend.NewZRPCFromConf(opts.confPath) if err != nil { log.WithFields(logrus.Fields{ "error": err, - }).Warn("HUSH3.conf failed, will try empty credentials for rpc") + }).Warn("DRAGONX.conf failed, will try empty credentials for rpc") - rpcClient, err = frontend.NewZRPCFromCreds("127.0.0.1:18031", "", "") + rpcClient, err = frontend.NewZRPCFromCreds("127.0.0.1:21769", "", "") if err != nil { log.WithFields(logrus.Fields{ diff --git a/common/common.go b/common/common.go index 113dd59..bda1efc 100644 --- a/common/common.go +++ b/common/common.go @@ -25,7 +25,7 @@ func GetSaplingInfo(rpcClient *rpcclient.Client) (int, int, string, string, int, if rpcErr != nil { errParts := strings.SplitN(rpcErr.Error(), ":", 2) errCode, err = strconv.ParseInt(errParts[0], 10, 32) - //Check to see if we are requesting a height the hushd doesn't have yet + //Check to see if we are requesting a height the dragonxd doesn't have yet if err == nil && errCode == -8 { return -1, -1, "", "", -1, -1, -1, nil } @@ -65,7 +65,7 @@ func GetCoinsupply(rpcClient *rpcclient.Client) (string, string, int, int, int, if rpcErr != nil { errParts := strings.SplitN(rpcErr.Error(), ":", 2) errCode, err = strconv.ParseInt(errParts[0], 10, 32) - //Check to see if we are requesting a height the hushd doesn't have yet + //Check to see if we are requesting a height the dragonxd doesn't have yet if err == nil && errCode == -8 { return "", "", -1, -1, -1, -1, nil } @@ -101,7 +101,7 @@ func getBlockFromRPC(rpcClient *rpcclient.Client, height int) (*walletrpc.Compac if rpcErr != nil { errParts := strings.SplitN(rpcErr.Error(), ":", 2) errCode, err = strconv.ParseInt(errParts[0], 10, 32) - //Check to see if we are requesting a height the hushd doesn't have yet + //Check to see if we are requesting a height the dragonxd doesn't have yet if err == nil && errCode == -8 { return nil, nil } @@ -166,7 +166,7 @@ func BlockIngestor(rpcClient *rpcclient.Client, cache *BlockCache, log *logrus.E if timeoutCount == 3 { log.WithFields(logrus.Fields{ "timeouts": timeoutCount, - }).Warn("unable to issue RPC call to hushd node 3 times") + }).Warn("unable to issue RPC call to dragonxd node 3 times") break } } diff --git a/frontend/rpc_client.go b/frontend/rpc_client.go index b1c730a..5723e7d 100644 --- a/frontend/rpc_client.go +++ b/frontend/rpc_client.go @@ -23,13 +23,13 @@ func NewZRPCFromConf(confPath string) (*rpcclient.Client, error) { } func NewZRPCFromCreds(addr, username, password string) (*rpcclient.Client, error) { - // Connect to local hush RPC server using HTTP POST mode. + // Connect to local DragonX RPC server using HTTP POST mode. connCfg := &rpcclient.ConnConfig{ Host: addr, User: username, Pass: password, - HTTPPostMode: true, // Hush only supports HTTP POST mode - DisableTLS: true, // Hush does not provide TLS by default + HTTPPostMode: true, // DragonX only supports HTTP POST mode + DisableTLS: true, // DragonX does not provide TLS by default } // Notice the notification parameter is nil since notifications are // not supported in HTTP POST mode. diff --git a/frontend/service.go b/frontend/service.go index 998628e..9916e6b 100644 --- a/frontend/service.go +++ b/frontend/service.go @@ -76,7 +76,7 @@ func (s *SqlStreamer) GetAddressTxids(addressBlockFilter *walletrpc.TransparentA s.log.Errorf("Got error: %s", rpcErr.Error()) errParts := strings.SplitN(rpcErr.Error(), ":", 2) errCode, err = strconv.ParseInt(errParts[0], 10, 32) - //Check to see if we are requesting a height the hushd doesn't have yet + //Check to see if we are requesting a height the dragonxd doesn't have yet if err == nil && errCode == -8 { return nil } @@ -181,7 +181,7 @@ func (s *SqlStreamer) GetTransaction(ctx context.Context, txf *walletrpc.TxFilte s.log.Errorf("Got error: %s", rpcErr.Error()) errParts := strings.SplitN(rpcErr.Error(), ":", 2) errCode, err = strconv.ParseInt(errParts[0], 10, 32) - //Check to see if we are requesting a height the hushd doesn't have yet + //Check to see if we are requesting a height the dragonxd doesn't have yet if err == nil && errCode == -8 { return nil, err } @@ -211,7 +211,7 @@ func (s *SqlStreamer) GetTransaction(ctx context.Context, txf *walletrpc.TxFilte s.log.Errorf("Got error: %s", rpcErr.Error()) errParts := strings.SplitN(rpcErr.Error(), ":", 2) errCode, err = strconv.ParseInt(errParts[0], 10, 32) - //Check to see if we are requesting a height the hushd doesn't have yet + //Check to see if we are requesting a height the dragonxd doesn't have yet if err == nil && errCode == -8 { return nil, err } @@ -249,8 +249,8 @@ func (s *SqlStreamer) GetLightdInfo(ctx context.Context, in *walletrpc.Empty) (* // TODO these are called Error but they aren't at the moment. // A success will return code 0 and message txhash. return &walletrpc.LightdInfo{ - Version: "0.1.1-hushlightd", - Vendor: "Silentdragonlite LightWalletD", + Version: "0.1.1-dragonxlightd", + Vendor: "DragonX LightWalletD", TaddrSupport: true, ChainName: chainName, SaplingActivationHeight: uint64(saplingHeight), @@ -285,7 +285,7 @@ func (s *SqlStreamer) GetCoinsupply(ctx context.Context, in *walletrpc.Empty) (* }, nil } -// SendTransaction forwards raw transaction bytes to a hushd instance over JSON-RPC +// SendTransaction forwards raw transaction bytes to a dragonxd instance over JSON-RPC func (s *SqlStreamer) SendTransaction(ctx context.Context, rawtx *walletrpc.RawTransaction) (*walletrpc.SendResponse, error) { // sendrawtransaction "hexstring" ( allowhighfees ) // diff --git a/monitor_lwd.sh b/monitor_lwd.sh new file mode 100755 index 0000000..22ef60f --- /dev/null +++ b/monitor_lwd.sh @@ -0,0 +1,123 @@ +#!/usr/bin/env bash +# Copyright 2024-2026 The DragonX Developers +# Released under GPLv3 +# +# Monitors lightwalletd and restarts it automatically if it crashes. +# Usage: ./monitor_lwd.sh & +# or: nohup ./monitor_lwd.sh >> /tmp/lwd-monitor.log 2>&1 & + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +LWD_BIN="$SCRIPT_DIR/lightwalletd" +LWD_ARGS="-bind-addr lite.dragonx.is:9069 -conf-file $HOME/.hush/DRAGONX/DRAGONX.conf -no-tls" +LOGFILE="$SCRIPT_DIR/lwd-monitor.log" +PIDFILE="/tmp/lwd-monitor.pid" +RESTART_DELAY=5 # seconds to wait before restarting after a crash +MAX_RAPID_RESTARTS=5 # max restarts within the rapid window before backing off +RAPID_WINDOW=120 # seconds — if this many restarts happen within this window, back off +BACKOFF_DELAY=60 # seconds to wait when backing off + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +log() { + echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOGFILE" +} + +cleanup() { + log "${YELLOW}Monitor shutting down...${NC}" + if [[ -n "${LWD_PID:-}" ]] && kill -0 "$LWD_PID" 2>/dev/null; then + log "Stopping lightwalletd (PID $LWD_PID)..." + kill "$LWD_PID" 2>/dev/null || true + wait "$LWD_PID" 2>/dev/null || true + fi + rm -f "$PIDFILE" + log "Monitor stopped." + exit 0 +} + +trap cleanup SIGINT SIGTERM + +# Prevent duplicate monitors +if [[ -f "$PIDFILE" ]]; then + OLD_PID=$(cat "$PIDFILE") + if kill -0 "$OLD_PID" 2>/dev/null; then + echo "Monitor already running (PID $OLD_PID). Exiting." + exit 1 + fi + rm -f "$PIDFILE" +fi +echo $$ > "$PIDFILE" + +# Check binary exists +if [[ ! -x "$LWD_BIN" ]]; then + log "${RED}ERROR: lightwalletd binary not found at $LWD_BIN${NC}" + log "Build it first with: make build" + rm -f "$PIDFILE" + exit 1 +fi + +# Check conf file exists +CONF_FILE="$HOME/.hush/DRAGONX/DRAGONX.conf" +if [[ ! -f "$CONF_FILE" ]]; then + log "${RED}ERROR: DRAGONX.conf not found at $CONF_FILE${NC}" + rm -f "$PIDFILE" + exit 1 +fi + +log "${GREEN}DragonX lightwalletd monitor started (PID $$)${NC}" +log "Binary: $LWD_BIN" +log "Args: $LWD_ARGS" + +restart_times=() +LWD_PID="" + +while true; do + # Start lightwalletd + log "${GREEN}Starting lightwalletd...${NC}" + $LWD_BIN $LWD_ARGS >> "$LOGFILE" 2>&1 & + LWD_PID=$! + log "lightwalletd started with PID $LWD_PID" + + # Wait for it to exit + wait "$LWD_PID" || true + EXIT_CODE=$? + LWD_PID="" + + if [[ $EXIT_CODE -eq 0 ]]; then + log "${YELLOW}lightwalletd exited cleanly (code 0). Not restarting.${NC}" + break + fi + + log "${RED}lightwalletd crashed with exit code $EXIT_CODE${NC}" + + # Track restart frequency for backoff + NOW=$(date +%s) + restart_times+=("$NOW") + + # Trim old entries outside the rapid window + CUTOFF=$((NOW - RAPID_WINDOW)) + filtered=() + for t in "${restart_times[@]}"; do + if (( t >= CUTOFF )); then + filtered+=("$t") + fi + done + restart_times=("${filtered[@]}") + + if (( ${#restart_times[@]} >= MAX_RAPID_RESTARTS )); then + log "${YELLOW}Too many restarts (${#restart_times[@]} in ${RAPID_WINDOW}s). Backing off for ${BACKOFF_DELAY}s...${NC}" + sleep "$BACKOFF_DELAY" + restart_times=() + else + log "Restarting in ${RESTART_DELAY}s..." + sleep "$RESTART_DELAY" + fi +done + +rm -f "$PIDFILE" +log "Monitor exiting." diff --git a/util/build.sh b/util/build.sh index 42825db..a414703 100755 --- a/util/build.sh +++ b/util/build.sh @@ -23,10 +23,10 @@ echo "+------'+------'+------'+------'+------'+------'+------'+------'+------'+- # now to compiling... echo "" -echo "You have go installed, so starting to compile Hush lightwalletd for you..." +echo "You have go installed, so starting to compile DragonX lightwalletd for you..." cd `pwd`/cmd/server go build -o lightwalletd main.go mv lightwalletd `pwd`/../../lightwalletd echo "" -echo "Hush lightwalletd is now compiled for you. Enjoy and reach out if you need support." +echo "DragonX lightwalletd is now compiled for you. Enjoy and reach out if you need support." echo "For options, run ./lightwalletd --help"