Skip to content

Conversation

@f321x
Copy link
Member

@f321x f321x commented Nov 24, 2025

I was unable to do a "Max" amount submarine swap because the fee_estimate function used by LNWallet.num_sats_can_send() uses a hardcoded fee_proportional_millionths to estimate the fee for the lightning payment.
When the actual fee calculated later is higher than the estimated fee the payment fails as the channel is unable to add the htlc sum including the real fees as the amount exceeds what the channel can add.
Using SimpleConfig.LIGHTNING_PAYMENT_FEE_MAX_MILLIONTHS seems more reliable here as it will always use the possible maximum fee the user is willing to pay for the fee estimate.

I was unable to do a "Max" amount submarine swap because the
`fee_estimate` function used by `LNWallet.num_sats_can_send()` uses a
hardcoded `fee_proportional_millionths` to estimate the fee for the
lightning payment. When the actual fee determined later is higher
than the estimated fee the payment fails as the channel is unable to add
the htlc sum including the real fees as the amount exceeds what the
channel can add.
Using `SimpleConfig.LIGHTNING_PAYMENT_FEE_MAX_MILLIONTHS`
seems more reliable here as it will always use the true maximum fee
the user is willing to pay for the fee estimate.
Comment on lines 2881 to 2885
# Here we have to guess a fee, because some callers (submarine swaps)
# use this method to initiate a payment, which would otherwise fail.
fee_base_msat = 5000 # FIXME ehh.. there ought to be a better way...
fee_proportional_millionths = 500 # FIXME
fee_proportional_millionths = self.config.LIGHTNING_PAYMENT_FEE_MAX_MILLIONTHS
# inverse of fee_for_edge_msat
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using SimpleConfig.LIGHTNING_PAYMENT_FEE_MAX_MILLIONTHS seems more reliable here as it will always use the possible maximum fee the user is willing to pay for the fee estimate.

Well, with your current diff, you are estimating with fee_base_msat = 5000 plus config.LIGHTNING_PAYMENT_FEE_MAX_MILLIONTHS. So for large payments, because of that 5 sat base fee, you are overestimating a bit.
For small payments, because of the cutoff, you are underestimating.

What I mean is that lnworker.fee_estimate is currently inverting:

def fee_for_edge_msat(forwarded_amount_msat: int, fee_base_msat: int, fee_proportional_millionths: int) -> int:
return fee_base_msat \
+ (forwarded_amount_msat * fee_proportional_millionths // 1_000_000)

but maybe what you are trying to do - if you just want to assume max fees - is to instead invert:

electrum/electrum/lnutil.py

Lines 2020 to 2023 in 5302606

# for small payments, fees <= constant cutoff are fine
# for large payments, the max fee is percentage-based
fee_msat = invoice_amount_msat * millionths_clamped // 1_000_000
fee_msat = max(fee_msat, cutoff_clamped)

@f321x f321x marked this pull request as draft November 26, 2025 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants