Repository navigation
Swap limits per provider; Spark swaps exit together once the wallet is full - #641
Merged
Merged
Conversation
…in and max A node's single Min/Max swap size becomes one pair per provider: the migration renames it to Loop's and copies it to 40swap's. Spark's default to SPARK_SWAP_MIN_SATS (50000, at least 10000) and SPARK_SWAP_MAX_SATS (2000000). Auto-liquidity now picks the provider first, among those whose min fits the excess balance, then swaps the most that provider takes (for Spark, also within its wallet's room).
REBALANCE_MAX_ATTEMPTS, REBALANCE_AMOUNT_BACKOFF_RATIO, REBALANCE_INITIAL_RETRY_DELAY_SECONDS and REBALANCE_RETRY_BACKOFF_MULTIPLIER become SEND_PAYMENT_*, like SEND_PAYMENT_MAX_PARTS: Spark swap payments will retry with them too. The old names are still read as fallbacks.
…nces A payment that fails for no route, a timeout or too little outbound liquidity is retried up to SEND_PAYMENT_MAX_ATTEMPTS attempts, each SEND_PAYMENT_AMOUNT_BACKOFF_RATIO of the previous one and never below the node's Spark min swap. The SSP only issues fixed-amount invoices, so each retry gets a fresh, smaller one, saved on the swap before the delay so the monitor never sees a failed payment. A persistent Quartz job (SparkSwapPaymentJob) pays it after the backoff delay, and only if the node has no record of it yet. The monitor's deadline follows the current invoice.
A cooperative exit's fee doesn't grow with its leaves, so paid swaps now wait in their Spark wallet and exit in one batch once it is full: the room left under its max balance is below the smallest Spark min swap of the nodes using it. One exit per destination wallet, of at most 100 leaves (open-ssp's limit), to one reserved address saved on every swap first; the on-chain fee is shared in proportion to what each swap brought in. A swap whose leaves can't move leaves the batch. Max swaps in flight counts a Spark swap only until it is paid, and the overdue alert counts from the first exit attempt.
The grid's single Min/Max Swap Amount toggles, which showed nothing, become one pair per provider (Loop, 40swap, Spark), hidden by default and now rendered; Spark's show the setting's value, marked as the default, when the node has none. A column layout saved before keeps its choices: new columns take their default and gone ones are dropped.
Jossec101
force-pushed
the
spark/batched-exits
branch
from
October 14, 2026 13:01
33d450d to
4689c11
Compare
AddPerProviderSwapAmounts, AddSparkPaymentRetries and AddSparkExitBatches become AddPerProviderSwapAmountsAndSparkExitBatches: the same schema and the same hand edits (Loop's pair renamed from the shared one and copied to 40swap's, SparkPaymentAttempt defaulting to 1), and the same model snapshot. A local database that applied the three must be recreated.
…at created the swap The background payment ran on the creating request's services, and their scope ends with the request: the database's context factory with it. The payment went through, but saving its outcome threw ObjectDisposedException, leaving it to MonitorSwapsJob, and a failed first attempt was never retried smaller. Task.Run now opens its own scope and pays with a SparkSwapService of it.
Undo the smaller retries of a failed Spark swap payment: a definitive failure fails the swap again, as before. SparkSwapPaymentJob, the retry audit action and the swaps' SparkPaymentAttempt and SparkInvoiceExpiresAt columns go, and the single migration is regenerated without them. The payment still runs in a scope of its own.
Only rebalances retry now, so REBALANCE_MAX_ATTEMPTS, REBALANCE_AMOUNT_BACKOFF_RATIO, REBALANCE_INITIAL_RETRY_DELAY_SECONDS and REBALANCE_RETRY_BACKOFF_MULTIPLIER keep their names, as on main.
…eir own A node's single Max swaps in flight becomes one per provider, so Loop can run one swap at a time while Spark runs several. Auto-liquidity counts each provider's swaps in flight and leaves out a provider at its max, choosing among the others; with every weighted provider at its max it swaps nothing. Spark's creation checks Spark's own. The Nodes page sets each next to the provider's swap sizes, and the grid shows them. The single migration renames the shared value to Loop's and copies it to 40swap's and Spark's.
Jossec101
marked this pull request as ready for review
October 16, 2026 14:45
Jossec101
enabled auto-merge (squash)
October 16, 2026 15:00
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SPARK_SWAP_MIN_SATS(50,000) andSPARK_SWAP_MAX_SATS(2,000,000).AddPerProviderSwapLimitsAndSparkExitBatches.