Skip to content

Commit 434e8b0

Browse files
committed
invoices: integrate settlement interceptor with invoice registry
This commit updates the invoice registry to utilize the settlement interceptor during the invoice settlement routine. It allows the interceptor to capture the invoice, providing interception clients an opportunity to determine the settlement outcome.
1 parent 14a56fc commit 434e8b0

File tree

1 file changed

+46
-1
lines changed

1 file changed

+46
-1
lines changed

invoices/invoiceregistry.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"time"
1010

1111
"github.com/lightningnetwork/lnd/clock"
12+
"github.com/lightningnetwork/lnd/fn"
1213
"github.com/lightningnetwork/lnd/lntypes"
1314
"github.com/lightningnetwork/lnd/lnwire"
1415
"github.com/lightningnetwork/lnd/queue"
@@ -74,6 +75,11 @@ type RegistryConfig struct {
7475
// KeysendHoldTime indicates for how long we want to accept and hold
7576
// spontaneous keysend payments.
7677
KeysendHoldTime time.Duration
78+
79+
// SettlementInterceptor is a service that intercepts invoices during
80+
// the settlement phase, enabling a subscribed client to determine the
81+
// settlement outcome.
82+
SettlementInterceptor *SettlementInterceptor
7783
}
7884

7985
// htlcReleaseEvent describes an htlc auto-release event. It is used to release
@@ -998,6 +1004,41 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
9981004
)
9991005

10001006
callback := func(inv *Invoice) (*InvoiceUpdateDesc, error) {
1007+
// Provide the invoice to the settlement interceptor to allow
1008+
// the interceptor's client an opportunity to manipulate the
1009+
// settlement process.
1010+
var interceptSession fn.Option[InterceptSession]
1011+
if i.cfg.SettlementInterceptor != nil {
1012+
clientReq := InterceptClientRequest{
1013+
ExitHtlcCircuitKey: ctx.circuitKey,
1014+
ExitHtlcAmt: ctx.amtPaid,
1015+
ExitHtlcExpiry: ctx.expiry,
1016+
CurrentHeight: uint32(ctx.currentHeight),
1017+
Invoice: *inv,
1018+
}
1019+
interceptSession =
1020+
i.cfg.SettlementInterceptor.Intercept(clientReq)
1021+
}
1022+
1023+
// If the interceptor service has provided a response, we'll
1024+
// use the interceptor session to wait for the client to respond
1025+
// with a settlement resolution.
1026+
interceptSession.WhenSome(func(session InterceptSession) {
1027+
log.Debug("Waiting for client response from " +
1028+
"settlement interceptor session")
1029+
1030+
select {
1031+
case resp := <-session.ClientResponseChannel:
1032+
log.Debugf("Received settlement interceptor "+
1033+
"response: %v", resp)
1034+
ctx.SkipAmountCheck = resp.SkipAmountCheck
1035+
1036+
case <-session.Quit:
1037+
// At this point, the interceptor session has
1038+
// quit.
1039+
}
1040+
})
1041+
10011042
updateDesc, res, err := updateInvoice(ctx, inv)
10021043
if err != nil {
10031044
return nil, err
@@ -1051,6 +1092,8 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
10511092

10521093
var invoiceToExpire invoiceExpiry
10531094

1095+
log.Debugf("Settlement resolution: %T %v", resolution, resolution)
1096+
10541097
switch res := resolution.(type) {
10551098
case *HtlcFailResolution:
10561099
// Inspect latest htlc state on the invoice. If it is found,
@@ -1099,6 +1142,8 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
10991142
// with our peer.
11001143
setID := ctx.setID()
11011144
settledHtlcSet := invoice.HTLCSet(setID, HtlcStateSettled)
1145+
log.Debugf("Settled htlc set size: %d", len(settledHtlcSet))
1146+
11021147
for key, htlc := range settledHtlcSet {
11031148
preimage := res.Preimage
11041149
if htlc.AMP != nil && htlc.AMP.Preimage != nil {
@@ -1183,7 +1228,7 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
11831228
}
11841229

11851230
// Now that the links have been notified of any state changes to their
1186-
// HTLCs, we'll go ahead and notify any clients wiaiting on the invoice
1231+
// HTLCs, we'll go ahead and notify any clients waiting on the invoice
11871232
// state changes.
11881233
if updateSubscribers {
11891234
// We'll add a setID onto the notification, but only if this is

0 commit comments

Comments
 (0)