In this commit, we introduce a new ValidatePayReqAmt helper function
in the lnrpc package that consolidates the logic for validating a
caller-specified payment amount against a BOLT11 invoice amount. The
helper handles three cases: zero-amount invoices (caller must specify
an amount), fixed-amount invoices with no caller override (use invoice
amount), and fixed-amount invoices with a caller override (allow
overpayment, reject underpayment).
This helper will be used in the next commit to fix a bug where
amt_msat was silently ignored when paying fixed-amount invoices.
Previously, the SendPaymentSync path in rpcserver.go silently ignored
the amt_msat field when paying a BOLT11 invoice that already contained
a fixed amount, and the SendPaymentV2 path in router_backend.go
rejected the request outright with "amount must not be specified when
paying a non-zero amount invoice". Both behaviors prevented users from
intentionally overpaying an invoice, which is permitted by the BOLT
spec.
In this commit, we replace the duplicated amount validation logic in
both extractPaymentIntent (rpcserver.go) and
extractIntentFromSendRequest (router_backend.go) with calls to the new
ValidatePayReqAmt helper. When a caller specifies amt_msat alongside a
fixed-amount invoice, the payment now proceeds as long as the
specified amount is at least the invoice amount. Underpayment is still
rejected with a clear error message.
Fixes https://github.com/lightningnetwork/lnd/issues/10541
In this commit, we add an integration test that verifies a payer can
overpay a fixed-amount BOLT11 invoice by specifying a larger amt_msat
in the SendPaymentV2 request. The test creates a 1000 sat invoice,
pays it with 1100 sat (1,100,000 msat), and asserts that both the
sender's payment record and the receiver's invoice reflect the
overpaid amount.
To make sure we don't cause force-closures because of commit sig
mismatches, we add a test case to verify that the retransmitted HTLC
matches the original HTLC.
We update the lightning channel state machine in some key areas. If the
noop TLV is set in the update_add_htlc custom records then we change the
entry type to noop. When settling the HTLC if the type is noop we credit
the satoshi amount back to the sender.
We add a new update type to the payment descriptor to describe this new
type of htlc. This type of HTLC will only end up being set if explicitly
signalled by external software.
We check the context of the payment lifecycle at the beginning of
the `resumepayment` loop. This will make sure we have always the
latest state of the payment before deciding on the next steps in
the function `decideNextStep`.
This demonstrates that the "imported" account behaves differently for a
wallet that's watch-only vs. normal. The testTaprootImportTapscriptFullKeyFundPsbt
test case succeeds in a normal run but fails in a remote-signing setup.
For some reason, an imported tapscript address ends up in the "default"
account when remote-signing but in the "imported" account for a normal
wallet.
In this commit, we add a new atomic bool to only permit a single gossip
backlog goroutine per peer. If we get a new reuqest that needs a backlog
while we're still processing the other, then we'll drop that request.