autoloop: support static loop-ins#1119
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces support for static-address-backed loop-ins within the existing autoloop engine. It enables operators to utilize static deposits for automated liquidity management, providing a more flexible alternative to traditional wallet-funded loop-ins. The changes include updates to the liquidity planner, budget accounting, and RPC interfaces to ensure static loop-ins are treated as first-class citizens in the autoloop lifecycle while maintaining safety and consistency. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces support for static-address loop-in swaps within the autoloop planner. It adds a new configuration option to select the loop-in source, updates the liquidity manager to handle static loop-in snapshots for budget and traffic accounting, and includes necessary changes to the RPC interface and storage layer to support these swaps. I have no feedback to provide.
dcb8742 to
4f42af0
Compare
|
@claude please review |
Code Review: autoloop: support static loop-insThis is a well-structured feature addition with clear separation of concerns, solid backward compatibility, and good test coverage. The design choices documented in the PR description are sensible — especially the intentional narrow scope (full deposits only, no change, no fallback to wallet loop-ins). Below are my findings organized by severity. Medium:
|
|
There is a finding regarding time consuming deposit selection: [P1] staticaddr/loopin/autoloop.go:198 can do exponential subset search over deposits while building a static loop-in candidate. This is on the autoloop suggestion path, so a static address with many small deposits can make the liquidity manager stall when trying to decide that no candidate exists. The simple high-impact guard is to sum filtered swappable deposits and return ErrNoAutoloopCandidate if total < minAmount; I’d also bound the number of candidates or switch away from raw DFS for impossible [min,max] ranges. I am currently looking to tAck the PR. |
There was a problem hiding this comment.
✅ tACK (pending the P1 item found in #1119 (comment))
I've tested the new mode with
loop --network=regtest setparams \
--autoloop \
--loopinsource=static-address
and then
loop --network=regtest setparams \
--autoloop \
--loopinsource=static-address \
--maxswapfee=10 \
--maxroutingfee=10 \
--maxprepayfee=1 \
--maxprepay=30000 \
--maxminer=1500000 \
--sweeplimit=3 \
--autobudget=200000 \
--autoinflight=2 \
--minamt=250000 \
--maxamt=5000000
while setting the ticker duration to 10s.
It only fired once the minimum amount of deposits was available. It then selected up to maxamt.
Very nice work!
Add a dedicated loop-in source enum to the liquidity parameters rpc and wire it through the internal parameter model and CLI. This keeps the source selection explicit before any static autoloop planning lands, so operators can choose between the legacy wallet-funded path and a future static-address-backed path without relying on implicit fallback behavior.
Move static loop-in label validation to the rpc boundary and remove the same check from the internal manager path. This keeps external requests aligned with the existing swap rpc surface while allowing internal autoloop callers to keep using reserved labels for automated swaps. The tests cover both sides of that contract: rpc requests still reject reserved labels, and the manager path accepts them.
Test-only change. This is needed to reuse it in another test.
Add the static-address helper that prepares full-deposit autoloop loop-ins without dispatching them. The helper selects no-change deposit sets, records explicit outpoints, and quotes the exact selected amount before the planner tries to dispatch anything. The tests cover the full-deposit selector, the quoted request construction, and excluded outpoint handling so later liquidity work can rely on a stable preparation surface.
Teach the liquidity manager to include persisted static loop-ins in budget accounting, in-flight limits, and peer traffic backoff. This adds the static fee model used for conservative accounting and passes storage errors through the relevant planner helpers. The daemon wiring now exposes static loop-ins to liquidity so the manager can see the same ongoing swaps that the static-address subsystem persists, while easy autoloop keeps working with the new fallible traffic lookup path.
Extend the public rpc surface for static autoloop integration without turning the planner on yet. SuggestSwaps responses can now carry static-address loop-in requests and the new planner reason for missing static candidates is mapped over rpc.
Wire static-address-backed loop-ins into the existing autoloop planner and dispatch path. Loop-in rules can now be converted into static candidates, prepared after global sorting, filtered with static fee limits, and dispatched through the static manager. This also fixes MaxAutoInFlight enforcement across all suggested swap types and adds planner tests for missing static candidates and mixed in-flight filtering.
Static autoloop testing surfaced a SuggestSwaps failure when the planner disqualified a custom asset channel. Add the missing AutoReason enum value and handle ReasonCustomChannelData.
Replace the recursive full-deposit autoloop selector with a bounded-memory DP implementation in staticaddr/loopin/autoloop_dp.go. The new selector keeps the existing no-change semantics, first finds the best reachable total, then applies the 25 percent band rule so earlier-expiring deposits can win inside that near-optimal range. The DP table is capped at 128 MiB and keeps exact satoshi sums alongside compressed bucket weights, so planning stays memory-bounded without allowing oversized candidates. The compressed weighting now rounds down with a minimum of one bucket, which avoids rejecting valid sums after multiple per-deposit rounding steps while leaving the exact-sum check as the real safety boundary.
Great catch! I replaced the exponential search with a DP over deposits. It uses up to 128 MiB of RAM for the candidate table. When the number of deposits is modest, it returns exact results, i.e. the same results the exponential search would have returned. With a very large number of deposits, it gradually reduces accuracy by increasing the bucket size from 1 satoshi to 2 satoshis, and so on. I also changed the objective function. The selector first finds the maximum total within the [min, max] range, using fewer deposits as a tie-breaker. It then looks at the band [best - (best - min) / 4, best] and chooses the best subset by expiry within that band. The goal is to keep larger swaps preferred while still trying to consume older, earlier-expiring deposits when the amount trade-off is small. I also applied these earlier Claude findings:
|
This adds static-address-backed loop-ins to the current autoloop engine.
What changes
static_loop_insuggestions, include them inforceautoloop, and enforceMaxAutoInFlightacross all suggested swap types.SuggestSwapsnow exposes static loop-in suggestions through a dedicated RPC field and includes the static no-candidate disqualification reason.AUTO_REASON_CUSTOM_CHANNEL_DATAis added, so custom asset channels are reported as disqualified instead of breaking the RPC response.Important design choices
fast=false.loop_insuggestions.Validation
1,000,000 satstatic deposit was suggested throughsuggestswaps, dispatched throughforceautoloop, completed successfully, moved the deposit toLOOPED_IN, increased outbound liquidity on the target BTC peer, and was not suggested again afterward.Pull Request Checklist
release_notes.mdif your PR contains major features, breaking changes or bugfixes