feat(pusher): add opt-in v2 WeTime ping signing
- Add WELIST_PING_SIG_VERSION (1 legacy, 2 canonical JSON); default 1
- Sign WELIST-PING-V2\n + compact sorted JSON covering url, chain, height,
median_time, last_block_hash, info, base_fee, version and sig_version
- Fetch info/base_fee/version from the local /{chain}/info endpoint and sign them
- Fall back to null metadata on fetch failure; skip the fetch for onion URLs
- Normalize the advertised URL and bound metadata to match the WeTime service
- Activate v2 in bal-pusher.sh and document the TXT record setup
- Add unit tests for canonical payloads, URL normalization, metadata and onion detection
Includes previously uncommitted local deployment hardening:
- pg-server.sh configurable loopback bind address, volume and recreate handling
- .env loading in bal-server.sh and bal-pusher.sh
- second bal-server/bal-pusher development scripts
This commit is contained in:
@@ -193,6 +193,23 @@ This is the async daemon that monitors the blockchain and pushes pending transac
|
||||
- Stats are inserted into `tbl_stats` with `ON CONFLICT(chain) DO UPDATE`.
|
||||
- The stats payload is signed with Ed25519 and POSTed to `{welist_url}/ping`.
|
||||
- The `WELIST_SERVER_URL` is validated via `is_valid_welist_url()` before sending (can be bypassed with `WELIST_SKIP_URL_VALIDATION=true`).
|
||||
- `WELIST_PING_SIG_VERSION` selects the signature scheme:
|
||||
- `1` (default): legacy concatenation of URL, chain, height, median time and
|
||||
block hash. The WeTime service verifies it against `/.pub_key.pem`.
|
||||
- `2`: canonical JSON signed with the `WELIST-PING-V2\n` prefix. The pusher
|
||||
fetches `info`, `base_fee` and `version` from the local
|
||||
`/{chain}/info` endpoint and signs them together with the block metadata.
|
||||
The WeTime service discovers the public key from a DNSSEC-validated
|
||||
`_welist-key.<host>` TXT record or from a v3 onion address, so no HTTP
|
||||
callback is needed. The `url` is trimmed of trailing slashes to match the
|
||||
service-side normalization; absent metadata is signed as `null`.
|
||||
- `bal-pusher.sh` sets `WELIST_PING_SIG_VERSION=2` for the development setup;
|
||||
remove that line to fall back to the legacy scheme.
|
||||
- To publish the v2 public key, derive the base64 SubjectPublicKeyInfo DER:
|
||||
`openssl pkey -in private_key.pem -pubout -outform DER | base64 -w0` and
|
||||
publish it in a DNSSEC-signed TXT record named `_welist-key.<host>` with value
|
||||
`v=we1; alg=ed25519; key=<base64>`. A v3 onion URL needs no DNS record: its
|
||||
Ed25519 identity key is embedded in the address.
|
||||
|
||||
### ZMQ Timeout Handling
|
||||
- Uses `set_rcvtimeo(5000)` (5-second timeout).
|
||||
@@ -208,5 +225,6 @@ All configuration is via environment variables (no config files):
|
||||
- `SSL_KEY_PATH`: Path to Ed25519 private key for signing stats.
|
||||
- `WELIST_SERVER_URL`: URL to POST stats to (validated against SSRF).
|
||||
- `WELIST_SKIP_URL_VALIDATION`: Bypass URL validation (for testing).
|
||||
- `WELIST_PING_SIG_VERSION`: WeTime ping signature scheme (`1` legacy, `2` canonical JSON).
|
||||
- `BAL_PUSHER_PREFER_IPV6`: Pin HTTP connection to IPv6 address.
|
||||
- Per-network: `BAL_PUSHER_{NETWORK}_HOST`, `_PORT`, `_DIR_PATH`, `_DB_FIELD`, `_COOKIE_FILE`, `_RPC_USER`, `_RPC_PASSWORD`, `_ZMQ_HASHBLOCK`.
|
||||
|
||||
Reference in New Issue
Block a user