Skip to content

graphsense-lib 2.19.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 13:44
· 24 commits to master since this release

[2.19.0] - 2026-10-28

graphsense-cli sync run replaces the per-network cron jobs with one continuously running sync daemon; the REST API gains address notifications (off by default) and drops the sunset /entities routes.

Upgrade notes

  • Python 3.10 is no longer supported (requires-python = ">=3.11, <3.14"). The Docker images were already on 3.13; the Python client still supports 3.10.
  • delta-update update always runs the full updater (formerly --updater-version 2). --updater-version 1, --write-new/--write-dirty are gone; --updater-version 2 is still accepted.
  • --write-batch-size 1 no longer selects a per-transaction mode; it is a normal WAL-protected batch of one block. A leftover *_deltaupdate_*_crashreport.err under /tmp marks a block that was only partly applied and is no longer read: finish that run with 2.18.x before upgrading, or 2.19 skips the rest of that block.
  • The /{currency}/entities/... routes and /addresses/{address}/entity answer 404 (sunset 2026-10-31); use the /clusters equivalents. The entity-named bulk operations and the deprecated entity fields stay.
  • notifications.service_token is refused by older gs-rest versions; set it only together with this version.
  • Dockerfile.transformation is removed; use the main image.

Web API + Python client

Added

  • Address notifications under /notifications/*, enabled with notifications.enabled and notifications.url. Subscriptions and the feed of notified transactions are forwarded to the gs-notifications service with the gateway's identity headers and an optional service_token. Requests are validated before forwarding (control characters in labels, oversized ids, hourly → 422); the service's answers are passed through unchanged, an unreachable service is 502, a timeout 504. Hidden from the OpenAPI spec and the Python client unless notifications.include_in_schema is set (then labelled beta).
  • /capabilities lists the deployment's optional services (services: name, availability, version, contract version, beta, and for notifications the supported networks), read from each service's /meta and cached for a minute.

Changed

  • entity is optional in the OpenAPI schema of Address, Cluster and Entity. The server still sends it; Python client: Address.entity is Optional[int].

Removed

  • The /{currency}/entities/... routes and /{currency}/addresses/{address}/entity (see Upgrade notes). Python client: EntitiesApi, AddressesApi.get_address_entity, EntityAddresses/NeighborEntities and graphsense raw entities are gone; using them raises an error naming the replacement.

Fixed

  • /search finds bech32 addresses written in uppercase (BC1Q…, as in QR codes), also by prefix.
  • A mixed-case bech32 address gets 400 "upper and lower case mixed" instead of "checksum mismatch".
  • Networks served by an external backend accept upper-case names (/BNB/...), like core networks.
  • Cluster neighbor search answers 400 for an unsupported key (e.g. actors) instead of 500.

Library

Added

  • graphsense-cli sync run: a daemon that keeps networks up to date continuously. Per network it polls the node and the raw/transformed heights and runs ingest from-node, delta-update update and Delta Lake compaction checks as child processes, so lag is one poll plus the reorg backoff instead of up to an hour. Configured under sync: (sync.networks); one daemon per network (-c) or per --channel. It checks for reorgs deeper than the backoff before every ingest, alerts on repeated failures and on lag, and stops cleanly on SIGTERM (stop_grace_seconds, default 480), so an image switch is a plain docker compose up -d. sync status, sync pause [--for] [--wait] and sync resume manage it; state lives in Redis when configured.
  • Ingest and delta-update defaults in the keyspace config (ingest_config.sinks, auto_compact, auto_compact_last_n, reorg_backoff_blocks; new delta_update_config with write_batch_size, parallel_workers, forward_fill_rates, pedantic), so manual runs, cron and the daemon behave the same. CLI flags still win.
  • ingest delta-lake auto-compact runs the compaction check on its own (exit 0 not due, 11 no schedule, 911 lock held).
  • SIGTERM unwinds graphsense-cli like Ctrl-C, so a stopped job releases its Redis locks.
  • Tagpack address validation: tagpack validate --address-validation {off,warn,error}, per-tag address_validation: skip, and --invalid-addresses-report <file.tsv> listing every invalid address with an offline hint (wrong network, hex-encoded, truncated, private key, autofill run, …). More networks are checked (EVM chains, SOL, XRP, and for multi-chain tokens ALGO, EOSIO, TON), against the tag's network rather than its currency; the token → chain list is updated. Undecoded escape sequences are reported.

Changed

  • Shorter built-in reorg backoff: zec 150 → 100 blocks, bch 15 → 10, still covering the deepest reorg the nodes accept.

Removed

  • Python 3.10 support, the v1 delta updater, the per-transaction UTXO delta-update mode and Dockerfile.transformation (see Upgrade notes). Security updates in the lockfile: Pillow 13.0.0, certifi, GitPython, virtualenv.

Fixed

  • Forward-fill no longer writes zero exchange rates for the newest block. When the raw tip was the only block without rates (the first block of a day, just after the previous day's rates arrived), the rate frontier came back as -1 and the delta update stored zero fiat values for that block.
  • Base58Check address validation checks version byte and length, so BTC no longer accepts private or extended keys and BCH no longer accepts TRON addresses; ZEC Sapling (zs1…) and unified (u1…) addresses are accepted. Mixed-case bech32 is named as such.
  • Tags by address, actor and cluster are paged in a stable order (tag id breaks confidence ties), so pages no longer repeat or drop tags.
  • ETH/TRX delta updates write the tx-id mapping and secondary-id buckets before the address rows, so a busy address no longer briefly answers 500 or misses its newest txs.
  • ETH/TRX delta updates with one worker no longer fail serializing token maps into the WAL.
  • ingest from-node exits 12 ("nothing to ingest") when the node is behind raw, instead of failing an assertion.
  • The post-ingest staleness alert is sent at most once an hour per currency.
  • LTC ingest recognises MWEB outputs instead of warning ScriptParseError for every block; stored data is unchanged.
  • TRX ingest's gRPC retry policy uses the 5 attempts gRPC allows (it silently clamped the configured 9), with backoff from 20 s up to 120 s, so a node restart of several minutes is ridden out as documented.
  • Forward-filling today's exchange rate is logged at INFO, not as an hourly WARNING; a missing earlier day still warns.

What's Changed

  • Address notifications: /notifications/* routes and services in /capabilities by @soad003 in #200
  • chore(deps): bump pyo3 from 0.29.2 to 0.29.3 in /rust/gs_clustering in the pyo3-arrow group across 1 directory by @dependabot[bot] in #195
  • chore(deps): bump the docker-images group across 1 directory with 2 updates by @dependabot[bot] in #196
  • Continuous sync daemon replacing per-currency cron jobs by @soad003 in #202

Full Changelog: v2.18.2...v2.19.0