forked from bitcoinafterlife/bal-server
- 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
6.4 KiB
6.4 KiB
API Reference
Quick Reference
- What this file contains: complete specification of the HTTP API, ZMQ messages, and RPC usage, with request/response examples.
- See also: 03_architecture_and_data_flow.md, 04_modules_detail.md, 06_database_schema.md, 07_deployment_and_ops.md
HTTP API (provided by bal-server)
Rate Limiting
All endpoints are rate-limited via actix-governor with a token-bucket algorithm. Defaults:
| Endpoint | Rate (req/s) | Burst |
|---|---|---|
POST /{network}/pushtxs |
1 | 3 |
POST /searchtx |
5 | 10 |
GET /{network}/info |
20 | 30 |
| All others | 50 | 100 |
Rate limits are configurable via BAL_SERVER_ACTIX_* environment variables.
GET /
- Description: Returns a static identification string (default: "Will Executor Server").
- Response: Plain text
200 OK.
GET /version
- Description: Returns the Cargo package version.
- Response:
text/plain(e.g.,0.3.2).
GET /.pub_key.pem
- Description: Returns the static Ed25519 public key PEM file for signature verification of remote stats.
- Response:
text/plainwith the PEM file content. - File:
public_key.pemin the project root (path configurable viaBAL_SERVER_PUB_KEY_PATH).
GET /:network/info
- Description: Returns JSON with the server's configuration for that specific network.
- Supported Networks:
bitcoin,testnet,testnet4,signet,regtest. - Response (200 OK):
{ "address": "bcrt1q...", "base_fee": 50000, "chain": "regtest", "info": "Will Executor Server", "version": "0.3.2" } - In xpub mode, the
addressfield contains a freshly derived P2WPKH address unique to the requesting IP. - Error:
404if the network is not configured or unknown.
GET /:network/stats
- Description: Returns statistics for the given network. Guarded by the
expose_statsconfiguration flag. - Response (200 OK): A JSON array of
StatsResponseobjects:[ { "report_date": "2024-07-20T12:00:00Z", "chain": "regtest", "totals": 42, "waiting": 10, "sent": 30, "failed": 2, "waiting_profit": 10000, "sent_profit": 30000, "missed_profit": 5000, "unique_inputs": 15 } ] - Error:
403or400if stats are not enabled or the network is unknown.
POST /:network/pushtxs
- Description: Accepts one or more raw hex Bitcoin transactions (newline-separated). The server deserializes each transaction, validates that the fee is paid to the correct
our_addressfor that network, and stores valid transactions in the database. - Request Body: Newline-separated raw hex transactions.
02000000000101...hex...\n 02000000000101...hex...\n - Response (200 OK): A JSON object with the results for the batch:
{ "accepted": 2, "rejected": 0, "details": [...] } - Response (400 Bad Request): If all transactions are invalid, the fee is missing, or the locktime is not acceptable.
- Response (413 Payload Too Limited): If the request body exceeds the configured max size (default 1 MiB).
- Security Note: Invalid transactions or those not paying the required fees are not inserted into the database.
POST /searchtx
- Description: Searches for a transaction by its
txid. The request body must contain exactly 64 hex characters. - Request Body:
{ "txid": "abc123def456..." } - Response (200 OK):
{ "txid": "abc123...", "status": 1, "tx": "020000000...", "our_address": "bcrt1q...", "our_fees": 1000, "reqid": "192.168.1.1" } - Response (400 Bad Request): If the txid is not exactly 64 hex characters.
- Response (404 Not Found): If the transaction is not found in the database.
ZMQ Messages (consumed by bal-pusher)
Topic: hashblock
- Format: A multipart ZMQ message. The first frame is the topic name (
hashblock), the second frame is the 32-byte block hash. - Trigger: When a new Bitcoin block is found by the local node.
- Action: The pusher fetches
getblockchaininfofrom the RPC, gets the updatedmediantimeandblocksheight, then queries and pushes pending transactions. - Endpoint: Per-network (e.g.,
tcp://127.0.0.1:28332for mainnet). - Timeout: 5 seconds (
ZMQ_RCVTIMEO). The pusher logs a warning after ~720 consecutive timeouts (~1 hour).
Bitcoin Core RPC Usage (used by bal-pusher)
sendrawtransaction
- Method:
sendrawtransaction(RPC2) - Parameters:
hexstring(the raw hex of the transaction to broadcast). - Description: Broadcasts the transaction to the Bitcoin network. If the transaction is invalid (e.g.,
bad-txns-inputs-missingorspent), the RPC will return an error with a negative code (e.g.,-25). - Error Handling: The pusher catches these errors, logs them, and updates the database status to
2(failed) with the error inpush_err.
getblockchaininfo
- Method:
getblockchaininfo(RPC1) - Parameters: None.
- Description: Returns the current blockchain state, including
mediantime(median timestamp of the last 11 blocks) andblocks(best block height). Used to evaluatenLockTimeof pending transactions.
getblock
- Method:
getblock(RPC1) - Parameters:
blockhash,verbosity(set to1for JSON with timestamp). - Description: Fetches block details. Used as an alternative for median time calculation.
RPC Authentication
Authentication is done via bitcoincore-rpc using either:
UserPass:BAL_PUSHER_{NETWORK}_RPC_USERandBAL_PUSHER_{NETWORK}_RPC_PASSWORD.CookieFile:$HOME/.bitcoin/{dir_path}.cookieor custom path viaBAL_PUSHER_{NETWORK}_COOKIE_FILE.
The client tries username/password auth first, then falls back to cookie file auth.
Ed25519 Stats Signing
The pusher signs the statistics payload before sending it to the welist server:
- Collects statistics from the database.
- Serializes the stats as JSON.
- Signs the JSON payload with the Ed25519 private key (
privkey.pem). - Sends the payload with the base64-encoded signature in the
X-Signatureheader. - The
welistserver can verify the signature using the public key served atGET /.pub_key.pem.