Releases: m0wer/neutrino-api
Release list
v1.3.0
Added
- Watched-only mempool tracker (
MEMPOOL_ENABLED). The daemon now
subscribes to every connected peer's incoming P2P messages, fetches each
announced transaction, and records the ones that pay or spend a watched
address. Unconfirmed UTXOs are surfaced in the existing/v1/utxos
endpoint withheight: 0, unconfirmed spends are overlaid on
/v1/utxo/{txid}/{vout}via newmempool_*fields, and watched mempool
txs can be fetched verbatim from a new/v1/tx/{txid}endpoint. Tracker
state is in-memory only; after each successful rescan pass it evicts
precisely the entries that just confirmed on-chain (rather than wiping
the whole view, which would drop still-unconfirmed entries because
mempool peers do not reliably re-announce already-acked txs). A 14-day
TTL sweeps stale entries; RBF replacements automatically evict the
prior entry.- New config:
MEMPOOL_ENABLED/--mempool(default:true) toggles
the tracker. - New request flag:
include_mempoolon/v1/utxos(request body) and
on/v1/utxo/{txid}/{vout}(query string), defaulttrue. Set to
falseto receive only the chain-only view. /v1/statusgainsmempool_enabledand (when enabled) amempool
object reporting tracker counts (entries,utxos,spends,
peers).- Privacy model: the daemon asks every peer for every announced tx
rather than only those matching a local heuristic, so peers cannot
learn which addresses the operator cares about. The bandwidth cost
is small because we only fetch the tx body once per inv (deduped by
txid across peers) and discard txs that don't touch a watched
script. Backed by a fork patch onlightninglabs/neutrinothat
stops droppingMSG_TXadvertisements when the local node hasn't
asked the peer to relay txs.
- New config:
- Add a production-ready
systemdservice example in README for running the
neutrinodbinary directly on Linux hosts (including Raspberry Pi), with a
signet-oriented configuration example.
Changed
- Docker image publishing now includes
linux/386,linux/arm/v7, and
linux/arm/v6in addition tolinux/amd64andlinux/arm64, expanding
compatibility to 32-bit x86 and broader 32-bit ARM Linux systems. - Release binary matrix now includes
linux-386,linux-armv7,
linux-armv6, andwindows-arm64artifacts in addition to the previous
linux-amd64,linux-arm64,darwin-amd64,darwin-arm64, and
windows-amd64outputs. - README now documents a signet Docker run example using
LISTEN_ADDR=0.0.0.0:38334and host port mapping38334:38334. - Bump the
lightninglabs/neutrinofork to
0d5f911(m0wer/neutrino), which gates the relaxedMSG_TX
relay behaviour behind the newConfig.MempoolEnabledflag instead
of unconditionally enabling it.
v1.2.0
Fixed
- Preserve earliest
last_start_heightacross incremental rescans.
Previously, every call toRescan()(including auto-sync passes that
start atlast_scanned_tip + 1) overwrote the persisted
last_start_heightwith the most recent invocation's start. This
destroyed the wallet's coverage record on disk: clients use
last_start_heighttogether withlast_scanned_tipto decide whether
the daemon has already scanned the requested lookback window and skip
redundant full rescans. The bug forced a full re-scan on every CLI
invocation, which manifested as a ~12 s rescan even when the daemon
had already scanned the entire requested range.LastStartHeightis
now only lowered (when the new start is earlier or no scan has ever
run); incremental scans no longer narrow the recorded coverage.
Added
- Continuous background sync of watched addresses (
AUTO_SYNC_WATCHED).
The daemon now subscribes to block-connected notifications from the chain
service and incrementally scans every new block for all watched addresses
in the background, keeping the persisted UTXO set up-to-date in real time.
After the initial/v1/rescan, subsequent/v1/utxosqueries return
immediately without requiring clients to re-trigger a rescan, and the
daemon also catches up on every restart so wallet startup is instant
even after extended downtime.- New config:
AUTO_SYNC_WATCHED/--auto-sync-watched(default:true)
enables the auto-sync goroutine. - New config:
AUTO_SYNC_INTERVAL_SEC/--auto-sync-interval(default:
30) sets the fallback poll interval used while waiting for initial
header sync and as a safety net if block-notification subscription is
unavailable. - Auto-sync skips when a manual rescan is already running and only starts
after the chain service reportsIsCurrent() == trueto avoid scanning
against an incomplete header chain.
- New config:
v1.1.0
Changed
- Replace HTTP header import with CDN compact filter (cfilter) prefetch.
Block headers and filter headers are now synced exclusively via P2P (trusted),
while compact block filters can be bulk-downloaded from a block-dn CDN and
verified against the P2P-synced filter headers before storage. This provides
a better trust/performance balance: headers come from P2P consensus, filters
are cryptographically verified against those headers, and the CDN is used
only as untrusted transport for large filter data.- New config:
CFILTER_CDN_AUTO/--cfilter-cdn-auto(default:true)
enables automatic cfilter download from block-dn after P2P header sync. - New config:
CFILTER_CDN_URL/--cfilter-cdn-urloverrides the
auto-resolved block-dn base URL. - Removed config:
HEADER_IMPORT_AUTO,HEADER_IMPORT_BLOCK_URL,
HEADER_IMPORT_FILTER_URLand their corresponding CLI flags. - Removed header import fallback retry logic from chain service startup.
- CDN filters are downloaded in 2000-filter chunks, parsed from CompactSize
varint binary format, and verified viaChainService.ImportCFilters(). - Add
ImportCFilter()andImportCFilters()methods to the neutrino fork
for verified bulk cfilter import.
- New config:
Fixed
- CDN chunk bounds now floor-align to include the containing chunk.
Previously, when the prefetch start height did not align to a chunk boundary,
the first available chunk was skipped, leaving a gap that required P2P
fallback. The start is now floor-aligned so the chunk containing the
requested start height is always downloaded. - CDN prefetch continues past failed chunks instead of aborting.
Previously, any CDN chunk failure (verification mismatch or HTTP error)
would abort the entire CDN prefetch, forcing P2P to fetch all remaining
filters. Now, failed chunks are retried with exponential backoff, and if
retries are exhausted the chunk is skipped. CDN continues with subsequent
chunks, and P2P fills only the specific gaps. CDN prefetch is aborted
only after 3 consecutive failures. - Pin neutrino fork dependency to pushed commit.
Replace local pathreplacedirective with versioned pseudo-version
pointing tom0wer/neutrino@c1b598b97446.
v1.0.1
Fixed
- Fix
.onionpeer hostname handling in ban checks by patching the neutrino
ban manager parser to support Tor v2/v3 addresses, so discovered onion peers
no longer triggerunsupported IP typeparse errors.
v1.0.0
Added
- Auto-TLS and API token authentication: The server now generates a self-signed TLS certificate (EC P-256) and a random API token on first start, protecting against eavesdropping and unauthorized access. Credentials are persisted in the data directory.
- Add
--no-auth/NO_AUTH=trueflag to disable TLS and token authentication (for development/regtest environments). - Add
--reset-authflag to regenerate TLS certificate and auth token, and clear privacy-sensitive data (watched addresses, UTXOs). - Add
GET /v1/versionendpoint returning{"version": "..."}for lightweight version diagnostics. - Include
versionandwatched_addressesfields inGET /v1/statusresponses. - Include
watched_addressesandserver_versioninGET /v1/rescan/statusresponses. - Add
X-Neutrino-Versionresponse header on JSON API responses. - Docker image major-version tags (e.g.,
ghcr.io/m0wer/neutrino-api:1): Users can pin to a major version for automatic minor/patch updates without breaking changes.
Changed
- BREAKING: Server now uses HTTPS and requires authentication by default. Previously the server listened on plain HTTP with no authentication. It now auto-generates a TLS certificate and auth token, and requires
Authorization: Bearer <token>on all requests. See the migration guide below.
Migration guide (upgrading to this version)
Existing deployments that relied on unauthenticated plain HTTP access will break after upgrading. Choose one of the following approaches:
-
Adopt TLS + auth (recommended for production): After starting the upgraded server, find the auto-generated auth token in
<datadir>/auth_token. Update your clients to use HTTPS and include theAuthorization: Bearer <token>header. If using self-signed TLS, configure your client to trust<datadir>/tls.cert. -
Disable auth (development/regtest only): Set
NO_AUTH=true(environment variable) or pass--no-authto restore the previous unauthenticated HTTP behavior. This is already set in the provideddocker-compose.ymlfor the regtest environment. -
Pin your Docker image to a major version tag to avoid future breaking changes from automatic pulls. Use
ghcr.io/m0wer/neutrino-api:0for the pre-auth behavior orghcr.io/m0wer/neutrino-api:1once v1.0.0 is released.
v0.10.0
Added
- Two-phase startup for faster initial sync with Tor setups: Added
--clearnet-initial-sync/CLEARNET_INITIAL_SYNC(default:true). When Tor is configured, the node now syncs block headers and filter headers over clearnet first, then restarts the chain service in Tor mode for privacy-sensitive operations.
Changed
- Compact filter prefetch is now opt-in:
--prefetchfilters/PREFETCH_FILTERSnow defaults tofalseto avoid downloading and storing the full historical filter set on first startup. - New prefetch lookback control: Added
--prefetchlookback/PREFETCH_LOOKBACK(default:105120, about 2 years). When prefetch is enabled andprefetchstart=0, the prefetch start height is auto-computed astip - lookback.
Fixed
- Spent UTXO detection in bulk endpoint:
POST /v1/utxoscould return already-spent UTXOs because the batchMatchAnyfilter scan missed spending blocks in certain cases. Added a per-UTXO spend verification pass after the main scan that uses single-scriptfilter.Match(the same approach used by the reliableGET /v1/utxo/{txid}/{vout}endpoint) to catch any spends missed by the batch scan.
v0.9.0
Added
- Persistent state across restarts (
rescan_state.db): Watched addresses, UTXO set, and rescan metadata (last scanned tip, start height) are now persisted to a separate bbolt database. On restart, the server restores its previous state so UTXOs are available immediately without re-scanning. The state store uses three buckets (watched_addrs,utxo_set,rescan_meta) and is optional (nil = no persistence) for backward compatibility with tests. - Incremental rescan: When a rescan is requested with a
start_heightwithin the already-scanned range, the scan starts fromLastScannedTip+1instead of re-scanning the entire range. If already up-to-date, returns immediately. This avoids redundant 52k+ block rescans after restarts. - Rescan fallback to watched addresses:
POST /v1/rescanwith an emptyaddressesfield now falls back to all previously watched addresses instead of silently doing nothing. - HTTP request/response logging middleware: Every API call is logged with method, path, status code, and duration. 4xx/5xx responses log at WARN level; 2xx at INFO level.
- Rescan progress logging: During block scanning, progress is logged every 10 seconds with blocks scanned/total, percentage, current height, blocks/sec, estimated time remaining, and filter match count. A final summary includes total blocks, duration, speed, filter matches, and detailed UTXO accounting (found/added/removed).
- Rescan handler request logging:
POST /v1/rescannow logs start_height, address count, and outpoint count at INFO level.
v0.8.0
Added
- Add reproducible release flow for
neutrinodbinaries with deterministic Go build flags andSOURCE_DATE_EPOCH. - Add
scripts/release-build-sign.shto build release binaries locally, generateSHA256SUMS, and create a detached GPG signature. - Add
scripts/verify-release-build.shas a one-command local reproducibility check against the signed digest. - Add release signature infrastructure under
signatures/with trusted key list and m0wer public key. - Add
addPeerssetting, similar toconnectPeers, that allows specifying peers to connect to without disabling peer discovery.
Changed
- Update release workflow to rebuild binaries in CI, verify checksums against committed
signatures/<version>/SHA256SUMS, verifySHA256SUMS.asc, and upload binaries plus signed digest files to GitHub releases.
v0.7.0
Added
- Add
GET /v1/rescan/statusendpoint that returns{"in_progress": bool}, allowing clients to poll until a background rescan completes instead of using a fixed sleep. - Add
block_heighttoUTXOSpendReportfor more efficient scans.
v0.6.1
Fixed
- Fixed UTXO endpoint to return HTTP 404 (Not Found) instead of 500 (Internal Server Error) when UTXO is not found
- Added proper error type handling for API errors:
NotFoundErrorreturns HTTP 404BadRequestErrorreturns HTTP 400- Invalid address or txid parameters now return 400 instead of 500