- Remove src/bin/bal-pusher-enhanced.rs (synchronous pusher variant) - Remove bal-pusher.env and bal-pusher.sh from git tracking (now in .gitignore) - Update all documentation to remove references to bal-pusher-enhanced: * 01_project_overview.md * 02_glossary_and_bitcoin_domain.md * 03_architecture_and_data_flow.md * 04_modules_detail.md * 05_api_reference.md (remove rawblock ZMQ section, update references) * 08_security_audit.md (remove references to bal-pusher-enhanced in DoS and ZMQ sections) * 09_references_and_links.md - Build verified: cargo check passes for bal-pusher and bal-server binaries
6.6 KiB
Module Details
Quick Reference
- What this file contains: detailed analysis of each Rust module and binary, including source code references.
- See also: 03_architecture_and_data_flow.md, 09_references_and_links.md
lib.rs
Location: src/lib.rs
This is the root of the library crate. It simply exports two public modules:
pub mod db;— the database interfacepub mod xpub;— the extended public key utilities
It contains no application logic.
db.rs (Database Interface)
Location: src/db.rs
This module contains all the logic for interacting with the SQLite database.
Key Functions
create_table: Creates the full database schema if it does not exist. Seesrc/db.rsfor theCREATE TABLEstatements.execute_insert: A batched, atomic SQL wrapper function that performs multiple insert operations inside a transaction.insert_tx: Inserts a transaction intotbl_tx.insert_inp: Inserts an input intotbl_inp.insert_out: Inserts an output intotbl_out.insert_xpub: Inserts an xpub intotbl_xpub.insert_address: Inserts a new derived address intotbl_address.get_pending_txs: Queriestbl_txfor transactions withstatus=0and valid locktime conditions.update_tx_status: Updatesstatusto1(sent) or2(failed) after a broadcast attempt.get_stats: Aggregates statistics for thetbl_statstable.get_address_by_ip: A query that joinstbl_addresswithtbl_xpubto find addresses by IP for rate limiting or reuse logic.
Design Notes
SQL queries are built using format! in many places. The execute_insert function attempts to batch inserts to reduce transaction overhead, but this is dependent on the SQLite version.
xpub.rs (Extended Public Key Utilities)
Location: src/xpub.rs
This module handles the derivation of Bitcoin addresses from extended public keys (xpub/zpub) and the creation of P2WPKH descriptors.
Key Functions
parse_xpub: Parses a Base58-encoded xpub/zpub string into abitcoin::bip32::Xpub.derive_address: Derives a P2WPKH (Bech32) address at a given address index from the xpub. Uses the BIP-84 path (m/84'/coin_type'/account'/0/index). UsesSecp256k1from thesecp256k1crate for elliptic curve math.get_descriptor: Generates a Bitcoin descriptor string for the xpub (e.g.,wpkh(.../0/*)), which is useful for wallet integration.checksum_verify: Verifies the Base58 checksum of an xpub/zpub string to prevent data corruption during entry.
Dependencies
bitcoin::bip32::Xpubsecp256k1::Secp256k1bs58for Base58 decodingbitcoin::Address::p2wpkhfor address creation
bal-server.rs (HTTP Server / API)
Location: src/bin/bal-server.rs
The main application binary that provides an async HTTP server.
Architecture
- Runtime:
tokio::mainwithrt-multi-thread. - HTTP Framework:
hyper(low-level) +hyper-util+http-body-util. Each connection is spawned as a newtokio::task. - Routing: Routes are matched using path regex and a simple match on the HTTP method. The router is implemented manually in
main.
Key Routes (implemented in source code)
GET /,GET /version: Returns static strings (name and version).GET /.pub_key.pem: Returns the Ed25519 public key PEM file for signature verification.GET /:network/info: Returns JSON with fee, address, and chain info. Networks:bitcoin,testnet,testnet4,signet,regtest.GET /:network/stats: Returns per-chain statistics ifexpose_statsis enabled.POST /:network/pushtxs: Accepts one or more raw hex transactions. It validates them, checks the fee output to theour_addressfor that network, and stores the transaction in the database. Seesrc/bin/bal-server.rsfor thepushtxsrequest body parsing logic.POST /searchtx: Accepts a txid in the request body and returns the transaction details, status, and fee breakdown.
Configuration
- The server reads environment variables and/or a config file (
confy). Default config is hardcoded forregtestdevelopment. db_file: The path to the SQLite database (e.g.,bal.db).bind_address: The address to listen on (e.g.,127.0.0.1:3031).expose_stats: A boolean flag to enable/disable the stats endpoint.
Error Handling
- WARNING: This binary uses
unwrap()andexpect()on many critical paths (e.g.,sqlite::open,Regex::new,req.collect()). A malformed request could crash the async task or even the entire runtime. This is a known vulnerability.
Static Public Key (/.pub_key.pem)
The server serves a static public_key.pem file. The corresponding private key (privkey.pem) is used by the pusher to sign statistics before sending them to the welist server. This file is located in the project root directory.
bal-pusher.rs (Async Transaction Pusher)
Location: src/bin/bal-pusher.rs
This is the async daemon that monitors the blockchain and pushes pending transactions.
Architecture
- Runtime:
tokio::main. - ZMQ:
zmq::Contextwith aSUBsocket that listens totcp://127.0.0.1:28332(or similar per-network port). The topic ishashblock(32-byte block hash). - RPC: It uses the
bitcoincore-rpcclient to callgetblockchaininfo(to get themediantime) andsendrawtransactionfor each transaction. - HTTP Client:
reqwestwith thejsonfeature. It sends a signed JSON POST to thewelistserver.
Key Logic
- On every
hashblockmessage, it callsmain_result(). main_resultcreates abitcoincore-rpcclient. If it fails, it panics (panic!("impossible to get client {}", e)), crashing the entire process.- It fetches
getblockchaininfoto get themediantime. - It queries the database for transactions with
status=0andlocktime < mediantime. - For each pending transaction, it calls
sendrawtransaction. - If
send_statsis enabled, it collects statistics, signs them withprivkey.pem, and sends them to the configuredwelistURL viareqwest. - It updates the database with the new status.
Configuration
zmq_endpoint: The ZMQ endpoint (e.g.,tcp://127.0.0.1:28332).rpc_url: The URL of the Bitcoin RPC (e.g.,http://127.0.0.1:18443).rpc_auth:user_passorcookie_file. The cookie path is constructed from theHOMEenvironment variable (e.g.,~/.bitcoin/.cookie).send_stats: A boolean that enables the remote server reporting.welist_url: The URL to POST to.ssl_key_path: The path to the Ed25519 private key (privkey.pem) for signing stats.