Skip to content

graphsense-lib 2.12.4

Choose a tag to compare

@github-actions github-actions released this 08 May 08:18
· 260 commits to master since this release

[2.12.4] 2026-05-08

Library (v2.12.4)

Changed

  • Gunicorn worker timeout raised 30 → 300 s in the Dockerfile. Wide BTC txs with ?include_heuristics=all legitimately need more than 30 s when the tagstore is cold; the previous limit silently SIGKILL'd the worker mid-request and APISIX returned 502 around 59 s (its own default route timeout retrying once on the upstream RST).
  • TagsService.get_tag_summaries_by_subject_ids now logs per-phase timings (pg_tags, cassandra_cluster_ids, pg_best_cluster, digest, total) at DEBUG and emits a WARNING when total ≥ 10 s. Future regressions in this hot path are pinpointable from logs without a profiler attach.
  • tagpack-tool sync now logs per-phase wall-clock at INFO. Each sub-step (init, per-repo clone / actorpack / tagpack insert, remove duplicates, refresh views, quality metrics, cluster-mapping staleness check, cluster-mapping import) is bracketed by start/done lines via a _timed_phase context manager, plus a final total. Operators can now see where time goes on multi-repo runs without instrumenting by hand.

Fixed

  • TagstoreDbAsync.get_best_cluster_tags_for_clusters shipped every cluster_definer tag back to Python (regression introduced in v2.12.1's pool-exhaustion fix). The batched SQL builder dropped the LIMIT 1 from the singleton query and reduced in Python, which is fine when each cluster has a handful of cluster_definer tags, but pathological for a heavily-tagged cluster: with joinedload(Tag.concepts) (a collection), the result set grows as cluster_tag_count × concepts_per_tag for each requested cluster. Observed: 298 s for one cluster on a wide BTC tx whose 78 inputs all mapped to the same heavily-tagged cluster (timing line: pg_best_cluster=298.149s out of total=298.633s). Rewritten as two queries: (1) SELECT DISTINCT ON (cluster_id) cluster_id, tag_id ... ORDER BY cluster_id, confidence.level DESC picks the winner per cluster at the DB layer with no joinedloads (result-set bounded by len(cluster_ids)), (2) hydrate Tag + relationships only for the winning tag_ids. Same external contract — parity tests in tests/web/test_tag_summaries_batch_parity.py continue to pass. Affects both call sites: get_tag_summaries_by_subject_ids (CoinJoin FP-suppression on wide UTXO txs) and entities_service.list_entity_neighbors with include_labels=true.

Build / packaging

Fixed

  • GHCR package description shows "No description provided" despite the Dockerfile setting LABEL org.opencontainers.image.description. Once buildx publishes an attestation manifest list (the default in build-push-action v5+, visible as "OS / Arch 2" on the GHCR page), the UI reads the description from the manifest annotation, not from the image-config LABEL. Fix in .github/workflows/github-packages-publish.yaml: set DOCKER_METADATA_ANNOTATIONS_LEVELS=manifest,index on docker/metadata-action, and pass both labels: ${{ steps.meta.outputs.labels }} and annotations: ${{ steps.meta.outputs.annotations }} to docker/build-push-action. Description text is sourced automatically from the GitHub repo description. Also bumped docker/metadata-action 5.0.0 → 5.10.0 (gains outputs.annotations + the DOCKER_METADATA_ANNOTATIONS_LEVELS env, both added in 5.5.0) and docker/build-push-action 5.0.0 → 6.19.2 (gains the annotations input, added in 5.1.0; v6 is a non-breaking bump that adds workflow-level build summaries).

Web API + Python client (webapi-2.12.0)

No changes.

Full Changelog: v2.12.3...v2.12.4