Skip to content

feat(tools): add scorer-inspect CLI with text/csv/json output#79

Draft
ovitrif wants to merge 1 commit intomainfrom
feat/scorer-inspect
Draft

feat(tools): add scorer-inspect CLI with text/csv/json output#79
ovitrif wants to merge 1 commit intomainfrom
feat/scorer-inspect

Conversation

@ovitrif
Copy link
Copy Markdown
Collaborator

@ovitrif ovitrif commented Apr 28, 2026

This PR adds a scorer-inspect workspace member — a small standalone CLI for offline diagnostics of LDK serialized scorer files. Same parser handles both the served latest.bin payloads (e.g. https://api.blocktank.to/scorer-prod, https://scores.zeusln.com/latest.bin) and the bytes returned by Node::export_pathfinding_scores, since both formats are wire-identical in current LDK.

Depends on:

Summary

  • New workspace member crates/scorer-inspect/ (binary, no library).
  • CLI: scorer-inspect <FILE> [--source served|exported] [--output text|csv|json] [--save PATH] [--top N] [--all] [--sort narrow|recent|history].
  • Output:
    • text (default) — short summary block + top-N channel rows for human review.
    • csv — summary row, blank line, then one row per channel (Sublime Text / spreadsheet friendly on multi-MB files).
    • json{ summary, channels } for tooling.
  • Sorting: narrow (smallest offset window first; highest-information entries), recent (most recently updated first), history (largest historical-bucket weight first; most probe-derived signal).
  • Auto-detection of source: not needed; both shapes are ChannelLiquidities-encoded today, the --source flag is metadata only.

Why a standalone crate instead of a method on Node: the user-facing question is "compare these .bin files" — including ones that didn't come from a live node (Zeus's served file, archived snapshots). A separate binary keeps the API surface clean and skips needing UDL bindings.

Test plan

  • cargo build -p scorer-inspect --release succeeds against the diagnostics-bearing rust-lightning branch.
  • Ran against live data:
    • curl -o /tmp/zeus.bin https://scores.zeusln.com/latest.bin (1.42 MB)
    • curl -o /tmp/blocktank.bin https://api.blocktank.to/scorer-prod (~80 KB)
    • All three output formats produced sensible results; CSV opens cleanly in Sublime Text; --top, --all, --sort flags all work.
  • cargo test --workspace from the ldk-node root — no regressions.
  • Pre-merge requirement: rust-lightning PR must be merged and [patch.crates-io] rev bumped to the merged commit. Until then this branch is buildable only against a local override.

Empirical findings already produced by this tool

A 3-way comparison (Zeus served file vs Blocktank served file) using the new CLI:

Metric Zeus Blocktank prod Ratio
File size ~1.4 MB ~80 KB 17.4×
Entries 6,801 390 17.4×
has_history populated 100% 100%
Single-bucket-single-observation entries 44.2% 19.7%

The 17.4× size ratio matches the 17.4× entry count exactly — there's no encoding trick. Zeus runs broad-but-shallow probing (44% of entries with single-observation history), Blocktank runs narrow-but-deep on a curated whitelist (only 20% single-observation, the rest with rich history).

🤖 Generated with Claude Code

scorer-inspect is a small standalone CLI for offline diagnostics of LDK
serialized scorer files - both the `latest.bin` style payloads served at
URLs like api.blocktank.to/scorer-prod or scores.zeusln.com/latest.bin
and the bytes returned by Node::export_pathfinding_scores. Both wire
formats are identical in current LDK (ProbabilisticScorer::write just
delegates to ChannelLiquidities::write), so the parser is a single
ChannelLiquidities::read; the --source flag is metadata only.

Output is configurable as plain text (default), CSV, or pretty-printed
JSON, optionally written to disk via --save. The summary section
reports entry count, history-populated percentage, and offset / bucket
weight distributions; the per-channel section can be limited via --top
or fully dumped via --all, and sorted by narrowest offset window,
recency, or historical bucket weight.

Depends on the diagnostics() accessors added to ChannelLiquidities and
ProbabilisticScorer in the synonymdev/rust-lightning fork. The ldk-node
[patch.crates-io] block is unchanged here; the rust-lightning PR must
land first and the rev pin must be bumped before this branch can merge.
For local development of this crate, point [patch.crates-io] at a
checkout of synonymdev/rust-lightning that has the diagnostics
accessors applied.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant