bal-server:
- Wire independent actix-governor buckets per endpoint class (pushtxs,
searchtx, info/stats, default) so polling a cheap endpoint can no longer
exhaust the push-txs budget; previously every limit was dead config
- Enforce BAL_SERVER_ACTIX_TIMEOUT_SECS via a request-timeout middleware that
returns 408 Request Timeout, covering slow request bodies
- De-duplicate txids within a single /pushtxs request body
- Replace the byte-slice xpub detection (panic on non-ASCII) with a safe
prefix check
bal-pusher:
- Handle malformed/empty ZMQ frames without indexing panics or UTF-8 expect
- Return an error from sign_message and skip the stats report instead of
panicking when the private key cannot be parsed
validation / db:
- Reject IPv4-mapped IPv6 targets (::ffff:a.b.c.d) in is_valid_welist_url
to close an SSRF bypass, with unit tests
- Use Path::starts_with for the SQLite forbidden-directory check so paths
like /etcfoo are not misclassified
misc:
- Add explicit secret patterns to .gitignore and sync the docs
- Use BAL_SERVER_DB_* / BAL_SERVER_PG_DSN in bal-pusher, Dockerfiles,
scripts and docs instead of the BAL_PUSHER_DB_* duplicates
- Default BAL_SERVER_URL to http://127.0.0.1:9133
- Extract PostgreSQL container startup into a shared pg-server.sh sourced by
bal-server.sh and bal-pusher.sh
- Read the Postgres password from BAL_PG_PASSWORD instead of hardcoding it,
and stop printing the password-bearing DSN
- Redact a real-looking Gitea token from .env.example (revoke it if it was live)
- Correct per-endpoint rate limit tables to reflect actual single global config
- Document RealIpKeyExtractor behavior (X-Real-IP / X-Forwarded-For behind proxy)
- Add BAL_SERVER_TRUSTED_PROXY env var to all relevant docs
- Update security audit and modules detail with proxy-aware rate limiting
- Fix framework references (actix-web, not hyper)
- Update all env var names (BAL_SERVER_*/BAL_PUSHER_* prefix)
- Add validation.rs module documentation
- Fix function signatures in xpub.rs and db.rs
- Update API response formats (InfoResponse, StatsResponse)
- Fix database schema (date_creation/date_update, push_err, tbl_stats)
- Mark fixed vulnerabilities with current status
- Add Docker support and actix tuning documentation
- Remove outdated references (confy, bal-stats.rs.dontcompile)
- Add regression test summary table
The welist host publishes both A and AAAA records. On networks where the
IPv4 route is broken (connection stalls after the TCP handshake) while
IPv6 works, the default connector may pick the broken family and the
report request hangs.
When BAL_PUSHER_PREFER_IPV6 is truthy, the pusher now resolves the welist
host itself and pins the reqwest client to its first IPv6 address; the
original hostname is still used for the Host header and TLS SNI. When the
variable is unset (default) or no AAAA record exists, behavior is
completely unchanged.
Includes unit tests for the URL host/port parsing and documentation in
docs/07_deployment_and_ops.md.
- Add docs/INDEX.md with navigable index and quick reference guides
- Add 9 knowledge base files covering project overview, Bitcoin domain,
architecture, modules, API reference, database schema, deployment/security
- Update AGENTS.md with knowledge base reference and update policy
- Add tests/sql_injection_tests.rs with regression tests for SQL injection
- Fix SQL injection vulnerabilities in bal-pusher.rs:
* Replace string-formatted UPDATE IN with loop + parameterized queries
* Replace string-formatted UPDATE push_err with parameterized query
* Add chain name validation in calculate_stats to prevent env var tampering
- Update .gitignore to exclude bal-pusher.env and bal-pusher.sh