feat(scoring): expose merged scorer output#3
Conversation
c7801e0 to
0a47329
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a5bf3e33aa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ChannelLiquidityMergeAction::Combine => { | ||
| entry.get_mut().merge(&other_liquidity); |
There was a problem hiding this comment.
Avoid combining no-decay entries with stale timestamps
When merge_without_decay callers return Combine for entries whose last_updated values differ, ChannelLiquidity::merge averages the offsets/history but leaves the existing entry's timestamps unchanged. Because this path intentionally skips normalization, the serialized merged score will later be decayed as if all of the averaged liquidity data came from the left-hand timestamp, causing over- or under-decay after the next time_passed; either normalize before combining or update the merged timestamps consistently here.
Useful? React with 👍 / 👎.
Stacked on #2.
Context
This PR adds the small write/merge/filter API surface needed by
scorer-kitafter the diagnostics API from #2.The immediate use case is offline score-file tooling: read serialized LDK scorer files, inspect their contents, compare them, selectively merge entries into a new
ChannelLiquiditiesfile, and write that file back out for downstream tooling.The goal is to let external tooling build an auditable scorer file instead of treating one scorer source as globally authoritative.
What Changed
ChannelLiquidities::merge(...)as a simple default merge helper. It decays both inputs to a shared timestamp, preserves unique entries, and combines duplicate short-channel-id entries using LDK existing per-channel merge semantics.ChannelLiquidities::merge_with(...)for policy-driven duplicate handling. The caller gets diagnostic views of both duplicate entries and can chooseKeepExisting,ReplaceWithOther, orCombineper channel.ChannelLiquidities::merge_without_decay(...)for offline overlay tooling that needs to preserve the baseline scorer exactly and only replace/insert selected incoming entries without normalizing every entry to a shared timestamp.ChannelLiquidities::remove(scid)so offline tooling can filter decoded scorer files before merging or re-serializing them.ChannelLiquidityMergeActionto make duplicate-resolution choices explicit.CombinedScorer::scores()so callers that use the existingCombinedScorer::merge(...)path can explicitly serialize the in-memory combined state. This intentionally does not changeCombinedScorerwrite behavior, which still persists local-only scores.Why Policy-Driven Merge
Blindly averaging every duplicate scorer entry is not obviously correct when combining independently generated scorer files. One source may be better for most overlapping channels, while another may be better for a smaller explicitly selected set.
This PR keeps the low-level LDK operation available, but lets external tooling own the actual merge policy. That policy can be deterministic and auditable: prefer richer history, prefer newer datapoints, preserve a baseline source by default, or explicitly overlay selected short-channel-ids.
Test Plan
cargo test -p lightning routing::scoring::tests::channel_liquidities_merge_without_decay_preserves_unselected_baseline_entries --features stdcargo test -p lightning --lib channel_liquidities_cargo test -p lightning --lib routing::scoring::tests::