Skip to content

feat: FeeOptimizerService + positive inbound fees (routing engine Phase 2a)#534

Closed
markettes wants to merge 1 commit into
feat/heuristic-fee-engine-phase1from
feat/heuristic-fee-engine-phase2a
Closed

feat: FeeOptimizerService + positive inbound fees (routing engine Phase 2a)#534
markettes wants to merge 1 commit into
feat/heuristic-fee-engine-phase1from
feat/heuristic-fee-engine-phase2a

Conversation

@markettes

Copy link
Copy Markdown
Contributor

Routing engine — Phase 2a (dynamic fee engine: logic + write primitive)

Stacked on #533 (Phase 1). Base branch is feat/heuristic-fee-engine-phase1, so this PR's diff shows only the Phase 2a layer. Review/merge #533 first.

This is the first of two Phase 2 PRs. It adds the pure decision logic and the LND-write primitive the actuator job (Phase 2b) will drive — no actuator runs yet, so behaviour is unchanged.

What's here

  • FeeOptimizerService (pure, singleton) — ComputeNextPolicy runs proportional control on the EMA-smoothed local ratio:
    • Authority split: defers to the rebalancer outside the rebalance deadband.
    • Fee-deadband no-op; per-step + min-delta clamps; outbound/inbound ppm floors & ceilings.
    • Direction table: d>0 (too local) → lower outbound + positive inbound; d<0 (too remote) → raise outbound + negative inbound.
    • Inbound collapses to ≤0 when the node disallows positive inbound.
    • Category baseline p₀ scales the term and seeds the first-eval "jump" toward the category baseline.
  • SetChannelFeePolicy gains an opt-in allowPositiveInboundFees flag (default false). Per review guidance, this reuses the existing method rather than adding a separate engine method: the manual/UI/gRPC path keeps its ≤0 inbound cap; the engine passes true and its writes are audit-marked EngineWrite=true.

Tests

  • FeeOptimizerServiceTests: direction table, clamps, inbound-collapse, first-eval seeding, FromConstants mapping.
  • LightningServiceTests: positive-inbound engine write path + audit marker.

Full suite green (337 passed, 1 skipped).

🤖 Generated with Claude Code

…fee-engine path

Phase 2a of the heuristic routing engine (stacked on Phase 1 / #533): the pure
decision logic and the LND-write primitive the fee optimizer job (2b) will drive.

- FeeOptimizerService (pure, singleton): ComputeNextPolicy runs proportional control
  on the EMA-smoothed local ratio. Authority split (defer to rebalancer outside the
  rebalance deadband), fee-deadband no-op, per-step + min-delta clamps, outbound/inbound
  ppm floors and ceilings, and inbound collapse to <=0 when the node disallows positive
  inbound. Category baseline (p0) both scales the term and seeds the first-eval "jump".
- SetChannelFeePolicy: per user request, no separate engine method — the existing method
  gains an opt-in allowPositiveInboundFees flag (default false). The manual/UI/gRPC path
  keeps its <=0 inbound cap unchanged; the engine passes true and its writes are marked
  EngineWrite=true in the audit log for filterability.
- Unit tests for the control-law direction table, clamps, inbound-collapse, first-eval
  seeding, and the positive-inbound write path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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