graphsense-lib 2.12.1
[2.12.1] 2026-05-07
Library (v2.12.1)
Added
-
Cluster mapping staleness check for
tagpack-tool: a sample of mapped addresses (biased toward large clusters viags_cluster_no_addr) is compared against the current clustering in the graph datastore, and a full cluster-mapping rerun is triggered only when divergence crosses a threshold. New flags:tagpack-tool sync --auto-rerun-cluster-mapping-with-env <env>(with--cluster-staleness-sample-size, default 2000, and--cluster-staleness-threshold, default 0.05).tagpack-tool tagstore insert-cluster-mappings --auto-rerun-if-stale(with--staleness-sample-size/--staleness-threshold).- New diagnostic command
tagpack-tool tagstore check-cluster-mapping-staleness --use-gs-lib-config-env <env>prints a per-network divergence table without writing to the DB.
The existing
--rerun-cluster-mapping-with-envand--run-cluster-mapping-with-envflags are unchanged. Eth-like networks (ETH/TRX) are skipped by the check sincecluster_id == address_idand drift is not possible. -
max_concurrencyfield onTagStoreReaderConfig(env:GRAPHSENSE_TAGSTORE_READ_MAX_CONCURRENCY) caps the number of concurrent Postgres-touching coroutines per gs-rest request. Defaults tomax(2, pool_size // 3)so a single wide request leaves headroom for concurrent traffic; can be overridden per-deployment. Amodel_validatorrejects configs wherepool_size + max_overflow < max_concurrencyat config load. The active value is read at runtime viaget_tagstore_max_concurrency()and registered on REST startup viaset_active_tagstore_config().
Changed
TagStoreReaderConfig.pool_timeoutdefault lowered from 300 → 10 seconds. The previous 5-minute default turned slow tagstore queries into request-time deadlocks; 10 seconds fails fast and surfaces real saturation.
Fixed
- gs-rest Postgres pool exhaustion (root cause of the 2026-05-04 incident). Every wide tagstore-touching code path now bounds its
asyncio.gatherfan-out via a sharedgather_boundedhelper usingTagStoreReaderConfig.max_concurrency. Sites covered:_any_input_is_exchangeheuristic (/<currency>/txs/{hash}?include_heuristics=allon wide BTC txs)_add_labels(everylist_*_neighbors include_labels=truerequest)list_address_neighborsper-neighborget_addressgather wheninclude_actors=true- BFS fan-out in
clusters_service(recursive_search,bfs) - Per-neighbor
db.get_entityfan-out inlist_entity_neighbors
- Per-call
AsyncSessionamplification inentities_service.list_entity_neighbors: replaced N×3 per-neighbor tagstore calls with three batched queries (get_best_cluster_tags_for_clusters,get_nr_tags_for_clusters,get_actors_for_clusters) sharing one Postgres session. Per-request session demand forpagesize=100&include_actors=truedrops from ~300 to 1. - Per-call session reuse in
entities_service.get_entity: three sequential tagstore calls now share oneAsyncSession(was 3).
Web API + Python client (webapi-2.12.0)
No changes.
Full Changelog: v2.12.0...v2.12.1