diff --git a/cln/cln_interceptor.go b/cln/cln_interceptor.go index 7514248..ebf8780 100644 --- a/cln/cln_interceptor.go +++ b/cln/cln_interceptor.go @@ -12,7 +12,6 @@ import ( "github.com/breez/lspd/cln_plugin/proto" "github.com/breez/lspd/config" - "github.com/breez/lspd/interceptor" "github.com/breez/lspd/lightning" "github.com/breez/lspd/shared" sphinx "github.com/lightningnetwork/lightning-onion" @@ -27,7 +26,7 @@ import ( ) type ClnHtlcInterceptor struct { - interceptor *interceptor.Interceptor + interceptor shared.InterceptHandler config *config.NodeConfig pluginAddress string client *ClnClient @@ -39,7 +38,7 @@ type ClnHtlcInterceptor struct { cancel context.CancelFunc } -func NewClnHtlcInterceptor(conf *config.NodeConfig, client *ClnClient, interceptor *interceptor.Interceptor) (*ClnHtlcInterceptor, error) { +func NewClnHtlcInterceptor(conf *config.NodeConfig, client *ClnClient, interceptor shared.InterceptHandler) (*ClnHtlcInterceptor, error) { i := &ClnHtlcInterceptor{ config: conf, pluginAddress: conf.Cln.PluginAddress, @@ -164,6 +163,8 @@ func (i *ClnHtlcInterceptor) intercept() error { interceptorClient.Send( i.failWithCode(request, interceptResult.FailureCode), ) + case shared.INTERCEPT_IGNORE: + // Do nothing case shared.INTERCEPT_RESUME: fallthrough default: @@ -203,7 +204,7 @@ func (i *ClnHtlcInterceptor) resumeWithOnion(request *proto.HtlcAccepted, interc log.Printf("resumeWithOnion: hex.DecodeString(%v) error: %v", request.Onion.Payload, err) return i.failWithCode(request, shared.FAILURE_TEMPORARY_CHANNEL_FAILURE) } - newPayload, err := encodePayloadWithNextHop(payload, interceptResult.Scid, interceptResult.AmountMsat) + newPayload, err := encodePayloadWithNextHop(payload, interceptResult.Scid, interceptResult.AmountMsat, interceptResult.FeeMsat) if err != nil { log.Printf("encodePayloadWithNextHop error: %v", err) return i.failWithCode(request, shared.FAILURE_TEMPORARY_CHANNEL_FAILURE) @@ -246,7 +247,7 @@ func (i *ClnHtlcInterceptor) failWithCode(request *proto.HtlcAccepted, code shar } } -func encodePayloadWithNextHop(payload []byte, scid lightning.ShortChannelID, amountToForward uint64) ([]byte, error) { +func encodePayloadWithNextHop(payload []byte, scid lightning.ShortChannelID, amountToForward uint64, feeMsat *uint64) ([]byte, error) { bufReader := bytes.NewBuffer(payload) var b [8]byte varInt, err := sphinx.ReadVarInt(bufReader, &b) @@ -308,8 +309,14 @@ func (i *ClnHtlcInterceptor) mapFailureCode(original shared.InterceptFailureCode switch original { case shared.FAILURE_TEMPORARY_CHANNEL_FAILURE: return "1007" + case shared.FAILURE_AMOUNT_BELOW_MINIMUM: + return "100B" + case shared.FAILURE_INCORRECT_CLTV_EXPIRY: + return "100D" case shared.FAILURE_TEMPORARY_NODE_FAILURE: return "2002" + case shared.FAILURE_UNKNOWN_NEXT_PEER: + return "400A" case shared.FAILURE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS: return "400F" default: diff --git a/main.go b/main.go index aa35028..d844077 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "encoding/hex" "encoding/json" "fmt" @@ -10,6 +11,7 @@ import ( "strings" "sync" "syscall" + "time" "github.com/breez/lspd/chain" "github.com/breez/lspd/cln" @@ -98,6 +100,7 @@ func main() { lsps2Store := postgresql.NewLsps2Store(pool) notificationService := notifications.NewNotificationService(notificationsStore) + ctx, cancel := context.WithCancel(context.Background()) openingService := shared.NewOpeningService(openingStore, nodesService) var interceptors []interceptor.HtlcInterceptor for _, node := range nodes { @@ -123,7 +126,21 @@ func main() { log.Fatalf("failed to initialize CLN client: %v", err) } - interceptor := interceptor.NewInterceptHandler(client, node.NodeConfig, interceptStore, openingService, feeEstimator, feeStrategy, notificationService) + legacyHandler := interceptor.NewInterceptHandler(client, node.NodeConfig, interceptStore, openingService, feeEstimator, feeStrategy, notificationService) + lsps2Handler := lsps2.NewInterceptHandler(lsps2Store, openingService, client, feeEstimator, &lsps2.InterceptorConfig{ + AdditionalChannelCapacitySat: uint64(node.NodeConfig.AdditionalChannelCapacity), + MinConfs: node.NodeConfig.MinConfs, + TargetConf: node.NodeConfig.TargetConf, + FeeStrategy: feeStrategy, + MinPaymentSizeMsat: node.NodeConfig.MinPaymentSizeMsat, + MaxPaymentSizeMsat: node.NodeConfig.MaxPaymentSizeMsat, + TimeLockDelta: node.NodeConfig.TimeLockDelta, + HtlcMinimumMsat: node.NodeConfig.MinHtlcMsat, + MppTimeout: time.Second * 90, + }) + go lsps2Handler.Start(ctx) + combinedHandler := shared.NewCombinedHandler(lsps2Handler, legacyHandler) + htlcInterceptor, err = cln.NewClnHtlcInterceptor(node.NodeConfig, client, combinedHandler) if err != nil { log.Fatalf("failed to initialize CLN interceptor: %v", err) } @@ -163,6 +180,8 @@ func main() { for _, interceptor := range interceptors { interceptor.Stop() } + + cancel() } for _, interceptor := range interceptors { diff --git a/shared/extra_fee_record.go b/shared/extra_fee_record.go new file mode 100644 index 0000000..aa7e4cb --- /dev/null +++ b/shared/extra_fee_record.go @@ -0,0 +1,9 @@ +package shared + +import "github.com/lightningnetwork/lnd/tlv" + +var ExtraFeeTlvType tlv.Type = 65536 + +func NewExtraFeeRecord(feeMsat *uint64) tlv.Record { + return tlv.MakePrimitiveRecord(ExtraFeeTlvType, feeMsat) +}