From 62e11a3e77e7cf1f12e5253a333366fd4ea4ac1f Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 8 Jul 2022 11:28:08 +0200 Subject: [PATCH 1/8] htlc intercept --- htlcInterceptor.go | 137 +++++++++++++++++++++++++++++++++++++++++++++ main.go | 94 ++++++++++++++----------------- 2 files changed, 179 insertions(+), 52 deletions(-) create mode 100644 htlcInterceptor.go diff --git a/htlcInterceptor.go b/htlcInterceptor.go new file mode 100644 index 0000000..51f7d15 --- /dev/null +++ b/htlcInterceptor.go @@ -0,0 +1,137 @@ +package main + +import ( + "context" + "encoding/hex" + "sync" + + "github.com/lightningnetwork/lnd/lnrpc" + "github.com/lightningnetwork/lnd/lnrpc/routerrpc" + log "github.com/sirupsen/logrus" + "google.golang.org/grpc" +) + +func dispatchHTLCInterceptor(ctx context.Context, conn *grpc.ClientConn) { + // wait group for channel acceptor + defer ctx.Value(ctxKeyWaitGroup).(*sync.WaitGroup).Done() + // get the lnd grpc connection + client := lnrpc.NewLightningClient(conn) + + acceptClient, err := client.ChannelAcceptor(ctx) + if err != nil { + panic(err) + } + log.Infof("Listening for incoming channel requests") + for { + req := lnrpc.ChannelAcceptRequest{} + err = acceptClient.RecvMsg(&req) + if err != nil { + log.Errorf(err.Error()) + } + log.Infof("New channel request from %s", hex.EncodeToString(req.NodePubkey)) + + var accept bool + + if Configuration.Mode == "whitelist" { + accept = false + for _, pubkey := range Configuration.Whitelist { + if hex.EncodeToString(req.NodePubkey) == pubkey { + accept = true + break + } + } + } else if Configuration.Mode == "blacklist" { + accept = true + for _, pubkey := range Configuration.Blacklist { + if hex.EncodeToString(req.NodePubkey) == pubkey { + accept = false + break + } + } + } + + res := lnrpc.ChannelAcceptResponse{} + if accept { + log.Infof("✅ [%s mode] Allow channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) + res = lnrpc.ChannelAcceptResponse{Accept: true, + PendingChanId: req.PendingChanId, + CsvDelay: req.CsvDelay, + MaxHtlcCount: req.MaxAcceptedHtlcs, + ReserveSat: req.ChannelReserve, + InFlightMaxMsat: req.MaxValueInFlight, + MinHtlcIn: req.MinHtlc, + } + + } else { + log.Infof("❌ [%s mode] Deny channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) + res = lnrpc.ChannelAcceptResponse{Accept: false, + Error: Configuration.RejectMessage} + } + err = acceptClient.Send(&res) + if err != nil { + log.Errorf(err.Error()) + } + } +} + +func processHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error { + for { + event, err := stream.Recv() + if err != nil { + return err + } + + if event.EventType != routerrpc.HtlcEvent_FORWARD { + continue + } + + switch event.Event.(type) { + case *routerrpc.HtlcEvent_SettleEvent: + log.Infof("Settle %s %s", event.IncomingChannelId, event.IncomingHtlcId) + + case *routerrpc.HtlcEvent_ForwardFailEvent: + log.Infof("ForwardFail %s %s", event.IncomingChannelId, event.IncomingHtlcId) + } + } +} + +func processInterceptor(interceptor routerrpc.Router_HtlcInterceptorClient) error { + for { + event, err := interceptor.Recv() + if err != nil { + return err + } + + // resumeChan := make(chan bool) + + print("I'm here") + // p.interceptChan <- interceptEvent{ + // circuitKey: circuitKey{ + // channel: event.IncomingCircuitKey.ChanId, + // htlc: event.IncomingCircuitKey.HtlcId, + // }, + // valueMsat: int64(event.OutgoingAmountMsat), + // resume: resumeChan, + // } + + // resume, ok := <-resumeChan + // if !ok { + // return errors.New("resume channel closed") + // } + resume := true + + response := &routerrpc.ForwardHtlcInterceptResponse{ + IncomingCircuitKey: event.IncomingCircuitKey, + } + if resume { + response.Action = routerrpc.ResolveHoldForwardAction_RESUME + } else { + response.Action = routerrpc.ResolveHoldForwardAction_FAIL + } + + err = interceptor.Send(response) + if err != nil { + return err + } + } +} diff --git a/main.go b/main.go index 9fc528e..40d00d6 100644 --- a/main.go +++ b/main.go @@ -5,8 +5,9 @@ import ( "encoding/hex" "fmt" "io/ioutil" + "sync" - "github.com/lightningnetwork/lnd/lnrpc" + "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/macaroons" log "github.com/sirupsen/logrus" @@ -15,6 +16,12 @@ import ( "gopkg.in/macaroon.v2" ) +type key int + +const ( + ctxKeyWaitGroup key = iota +) + // gets the lnd grpc connection func getClientConnection(ctx context.Context) (*grpc.ClientConn, error) { creds, err := credentials.NewClientTLSFromFile(Configuration.TLSPath, "") @@ -52,65 +59,48 @@ func trimPubKey(pubkey []byte) string { } func main() { - conn, err := getClientConnection(context.Background()) + ctx := context.Background() + // conn, err := getClientConnection(ctx) + // if err != nil { + // panic(err) + // } + + var wg sync.WaitGroup + ctx = context.WithValue(ctx, ctxKeyWaitGroup, &wg) + wg.Add(1) + + // client := lnrpc.NewLightningClient(conn) + // go dispatchChannelAcceptor(ctx, conn, client) + + // htlc interceptor + var router routerrpc.RouterClient + stream, err := router.SubscribeHtlcEvents(ctx, &routerrpc.SubscribeHtlcEventsRequest{}) if err != nil { - panic(err) + return } - client := lnrpc.NewLightningClient(conn) - acceptClient, err := client.ChannelAcceptor(context.Background()) + interceptor, err := router.HtlcInterceptor(ctx) if err != nil { - panic(err) + return } - log.Infof("Listening for incoming channel requests") - for { - req := lnrpc.ChannelAcceptRequest{} - err = acceptClient.RecvMsg(&req) + + log.Info("HTLC Interceptor registered") + + go func() { + err := processHtlcEvents(stream) if err != nil { - log.Errorf(err.Error()) + log.Error("htlc events error", + "err", err) } - log.Infof("New channel request from %s", hex.EncodeToString(req.NodePubkey)) + }() - var accept bool - - if Configuration.Mode == "whitelist" { - accept = false - for _, pubkey := range Configuration.Whitelist { - if hex.EncodeToString(req.NodePubkey) == pubkey { - accept = true - break - } - } - } else if Configuration.Mode == "blacklist" { - accept = true - for _, pubkey := range Configuration.Blacklist { - if hex.EncodeToString(req.NodePubkey) == pubkey { - accept = false - break - } - } - } - - res := lnrpc.ChannelAcceptResponse{} - if accept { - log.Infof("✅ [%s mode] Allow channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) - res = lnrpc.ChannelAcceptResponse{Accept: true, - PendingChanId: req.PendingChanId, - CsvDelay: req.CsvDelay, - MaxHtlcCount: req.MaxAcceptedHtlcs, - ReserveSat: req.ChannelReserve, - InFlightMaxMsat: req.MaxValueInFlight, - MinHtlcIn: req.MinHtlc, - } - - } else { - log.Infof("❌ [%s mode] Deny channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) - res = lnrpc.ChannelAcceptResponse{Accept: false, - Error: Configuration.RejectMessage} - } - err = acceptClient.Send(&res) + go func() { + err := processInterceptor(interceptor) if err != nil { - log.Errorf(err.Error()) + log.Error("interceptor error", + "err", err) } - } + }() + + wg.Wait() } From 4cd3bc9d6ac36f49b4e7f0516e9ea1e4e25ac46a Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 8 Jul 2022 11:41:42 +0200 Subject: [PATCH 2/8] channel acceptor --- channelAcceptor.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 channelAcceptor.go diff --git a/channelAcceptor.go b/channelAcceptor.go new file mode 100644 index 0000000..9811c21 --- /dev/null +++ b/channelAcceptor.go @@ -0,0 +1,72 @@ +package main + +import ( + "context" + "encoding/hex" + "sync" + + "github.com/lightningnetwork/lnd/lnrpc" + log "github.com/sirupsen/logrus" + "google.golang.org/grpc" +) + +func dispatchChannelAcceptor(ctx context.Context, conn *grpc.ClientConn, client lnrpc.LightningClient) { + // wait group for channel acceptor + defer ctx.Value(ctxKeyWaitGroup).(*sync.WaitGroup).Done() + // get the lnd grpc connection + acceptClient, err := client.ChannelAcceptor(ctx) + if err != nil { + panic(err) + } + log.Infof("Listening for incoming channel requests") + for { + req := lnrpc.ChannelAcceptRequest{} + err = acceptClient.RecvMsg(&req) + if err != nil { + log.Errorf(err.Error()) + } + log.Infof("New channel request from %s", hex.EncodeToString(req.NodePubkey)) + + var accept bool + + if Configuration.Mode == "whitelist" { + accept = false + for _, pubkey := range Configuration.Whitelist { + if hex.EncodeToString(req.NodePubkey) == pubkey { + accept = true + break + } + } + } else if Configuration.Mode == "blacklist" { + accept = true + for _, pubkey := range Configuration.Blacklist { + if hex.EncodeToString(req.NodePubkey) == pubkey { + accept = false + break + } + } + } + + res := lnrpc.ChannelAcceptResponse{} + if accept { + log.Infof("✅ [%s mode] Allow channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) + res = lnrpc.ChannelAcceptResponse{Accept: true, + PendingChanId: req.PendingChanId, + CsvDelay: req.CsvDelay, + MaxHtlcCount: req.MaxAcceptedHtlcs, + ReserveSat: req.ChannelReserve, + InFlightMaxMsat: req.MaxValueInFlight, + MinHtlcIn: req.MinHtlc, + } + + } else { + log.Infof("❌ [%s mode] Deny channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) + res = lnrpc.ChannelAcceptResponse{Accept: false, + Error: Configuration.RejectMessage} + } + err = acceptClient.Send(&res) + if err != nil { + log.Errorf(err.Error()) + } + } +} From ab0edab364f6b6abd3ca6dd89c3b0bdb96590966 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 8 Jul 2022 12:05:01 +0200 Subject: [PATCH 3/8] htlc interceptor works --- channelAcceptor.go | 2 +- htlcInterceptor.go | 96 ++++------------------------------------------ main.go | 28 +++++++------- 3 files changed, 23 insertions(+), 103 deletions(-) diff --git a/channelAcceptor.go b/channelAcceptor.go index 9811c21..96c2acf 100644 --- a/channelAcceptor.go +++ b/channelAcceptor.go @@ -60,7 +60,7 @@ func dispatchChannelAcceptor(ctx context.Context, conn *grpc.ClientConn, client } } else { - log.Infof("❌ [%s mode] Deny channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) + log.Infof("❌ [%s mode] Reject channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) res = lnrpc.ChannelAcceptResponse{Accept: false, Error: Configuration.RejectMessage} } diff --git a/htlcInterceptor.go b/htlcInterceptor.go index 51f7d15..46d8ca2 100644 --- a/htlcInterceptor.go +++ b/htlcInterceptor.go @@ -1,79 +1,10 @@ package main import ( - "context" - "encoding/hex" - "sync" - - "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" log "github.com/sirupsen/logrus" - "google.golang.org/grpc" ) -func dispatchHTLCInterceptor(ctx context.Context, conn *grpc.ClientConn) { - // wait group for channel acceptor - defer ctx.Value(ctxKeyWaitGroup).(*sync.WaitGroup).Done() - // get the lnd grpc connection - client := lnrpc.NewLightningClient(conn) - - acceptClient, err := client.ChannelAcceptor(ctx) - if err != nil { - panic(err) - } - log.Infof("Listening for incoming channel requests") - for { - req := lnrpc.ChannelAcceptRequest{} - err = acceptClient.RecvMsg(&req) - if err != nil { - log.Errorf(err.Error()) - } - log.Infof("New channel request from %s", hex.EncodeToString(req.NodePubkey)) - - var accept bool - - if Configuration.Mode == "whitelist" { - accept = false - for _, pubkey := range Configuration.Whitelist { - if hex.EncodeToString(req.NodePubkey) == pubkey { - accept = true - break - } - } - } else if Configuration.Mode == "blacklist" { - accept = true - for _, pubkey := range Configuration.Blacklist { - if hex.EncodeToString(req.NodePubkey) == pubkey { - accept = false - break - } - } - } - - res := lnrpc.ChannelAcceptResponse{} - if accept { - log.Infof("✅ [%s mode] Allow channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) - res = lnrpc.ChannelAcceptResponse{Accept: true, - PendingChanId: req.PendingChanId, - CsvDelay: req.CsvDelay, - MaxHtlcCount: req.MaxAcceptedHtlcs, - ReserveSat: req.ChannelReserve, - InFlightMaxMsat: req.MaxValueInFlight, - MinHtlcIn: req.MinHtlc, - } - - } else { - log.Infof("❌ [%s mode] Deny channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) - res = lnrpc.ChannelAcceptResponse{Accept: false, - Error: Configuration.RejectMessage} - } - err = acceptClient.Send(&res) - if err != nil { - log.Errorf(err.Error()) - } - } -} - func processHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error { for { event, err := stream.Recv() @@ -87,10 +18,10 @@ func processHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error switch event.Event.(type) { case *routerrpc.HtlcEvent_SettleEvent: - log.Infof("Settle %s %s", event.IncomingChannelId, event.IncomingHtlcId) + log.Infof("Event: Settle %d %d", event.IncomingChannelId, event.IncomingHtlcId) case *routerrpc.HtlcEvent_ForwardFailEvent: - log.Infof("ForwardFail %s %s", event.IncomingChannelId, event.IncomingHtlcId) + log.Infof("Event: ForwardFail %d %d", event.IncomingChannelId, event.IncomingHtlcId) } } } @@ -102,30 +33,17 @@ func processInterceptor(interceptor routerrpc.Router_HtlcInterceptorClient) erro return err } - // resumeChan := make(chan bool) - - print("I'm here") - // p.interceptChan <- interceptEvent{ - // circuitKey: circuitKey{ - // channel: event.IncomingCircuitKey.ChanId, - // htlc: event.IncomingCircuitKey.HtlcId, - // }, - // valueMsat: int64(event.OutgoingAmountMsat), - // resume: resumeChan, - // } - - // resume, ok := <-resumeChan - // if !ok { - // return errors.New("resume channel closed") - // } - resume := true + // decision for routing + accept := false response := &routerrpc.ForwardHtlcInterceptResponse{ IncomingCircuitKey: event.IncomingCircuitKey, } - if resume { + if accept { + log.Infof("✅ Accept HTLC (%d sat, %s)", event.IncomingAmountMsat/1000, event.IncomingCircuitKey.String()) response.Action = routerrpc.ResolveHoldForwardAction_RESUME } else { + log.Infof("❌ Reject HTLC (%d sat, %s)", event.IncomingAmountMsat/1000, event.IncomingCircuitKey.String()) response.Action = routerrpc.ResolveHoldForwardAction_FAIL } diff --git a/main.go b/main.go index 40d00d6..35db6dc 100644 --- a/main.go +++ b/main.go @@ -60,30 +60,24 @@ func trimPubKey(pubkey []byte) string { func main() { ctx := context.Background() - // conn, err := getClientConnection(ctx) - // if err != nil { - // panic(err) - // } + conn, err := getClientConnection(ctx) + if err != nil { + panic(err) + } var wg sync.WaitGroup ctx = context.WithValue(ctx, ctxKeyWaitGroup, &wg) wg.Add(1) - // client := lnrpc.NewLightningClient(conn) + // channel acceptor // go dispatchChannelAcceptor(ctx, conn, client) - // htlc interceptor - var router routerrpc.RouterClient + // htlc event subscriber, reports on incoming htlc events + router := routerrpc.NewRouterClient(conn) stream, err := router.SubscribeHtlcEvents(ctx, &routerrpc.SubscribeHtlcEventsRequest{}) if err != nil { return } - interceptor, err := router.HtlcInterceptor(ctx) - if err != nil { - return - } - - log.Info("HTLC Interceptor registered") go func() { err := processHtlcEvents(stream) @@ -93,6 +87,14 @@ func main() { } }() + // interceptor, decide whether to accept or reject + interceptor, err := router.HtlcInterceptor(ctx) + if err != nil { + return + } + + log.Info("HTLC Interceptor registered") + go func() { err := processInterceptor(interceptor) if err != nil { From 5a006119840d5d7839b9c90fdc3401a1d0b77858 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 8 Jul 2022 12:28:54 +0200 Subject: [PATCH 4/8] refactor --- htlcInterceptor.go | 56 ++++++++++++++++++++++++++++++++++++++++--- main.go | 60 ++++++++++++++++++++++++---------------------- 2 files changed, 85 insertions(+), 31 deletions(-) diff --git a/htlcInterceptor.go b/htlcInterceptor.go index 46d8ca2..e7c4d8f 100644 --- a/htlcInterceptor.go +++ b/htlcInterceptor.go @@ -1,10 +1,48 @@ package main import ( + "context" + "math/rand" + + "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" log "github.com/sirupsen/logrus" + "google.golang.org/grpc" ) +func dispatchHTLCAcceptor(ctx context.Context, conn *grpc.ClientConn, client lnrpc.LightningClient) { + // htlc event subscriber, reports on incoming htlc events + router := routerrpc.NewRouterClient(conn) + stream, err := router.SubscribeHtlcEvents(ctx, &routerrpc.SubscribeHtlcEventsRequest{}) + if err != nil { + return + } + + go func() { + err := processHtlcEvents(stream) + if err != nil { + log.Error("htlc events error", + "err", err) + } + }() + + // interceptor, decide whether to accept or reject + interceptor, err := router.HtlcInterceptor(ctx) + if err != nil { + return + } + + go func() { + err := processInterceptor(interceptor) + if err != nil { + log.Error("interceptor error", + "err", err) + } + }() + + log.Info("Listening for incoming HTLCs") +} + func processHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error { for { event, err := stream.Recv() @@ -18,11 +56,18 @@ func processHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error switch event.Event.(type) { case *routerrpc.HtlcEvent_SettleEvent: - log.Infof("Event: Settle %d %d", event.IncomingChannelId, event.IncomingHtlcId) + log.Infof("HTLC SettleEvent (chan_id:%d htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) case *routerrpc.HtlcEvent_ForwardFailEvent: - log.Infof("Event: ForwardFail %d %d", event.IncomingChannelId, event.IncomingHtlcId) + log.Infof("HTLC ForwardFailEvent (chan_id:%d htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) + + case *routerrpc.HtlcEvent_ForwardEvent: + log.Infof("HTLC ForwardEvent (chan_id:%d htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) + + case *routerrpc.HtlcEvent_LinkFailEvent: + log.Infof("HTLC LinkFailEvent (chan_id:%d htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) } + } } @@ -34,11 +79,16 @@ func processInterceptor(interceptor routerrpc.Router_HtlcInterceptorClient) erro } // decision for routing - accept := false + log.Infof("Received HTLC. Making random 50/50 decision...") + accept := true + if rand.Intn(2) == 0 { + accept = false + } response := &routerrpc.ForwardHtlcInterceptResponse{ IncomingCircuitKey: event.IncomingCircuitKey, } + if accept { log.Infof("✅ Accept HTLC (%d sat, %s)", event.IncomingAmountMsat/1000, event.IncomingCircuitKey.String()) response.Action = routerrpc.ResolveHoldForwardAction_RESUME diff --git a/main.go b/main.go index 35db6dc..bce388d 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,7 @@ import ( "io/ioutil" "sync" - "github.com/lightningnetwork/lnd/lnrpc/routerrpc" + "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/macaroons" log "github.com/sirupsen/logrus" @@ -64,44 +64,48 @@ func main() { if err != nil { panic(err) } + client := lnrpc.NewLightningClient(conn) var wg sync.WaitGroup ctx = context.WithValue(ctx, ctxKeyWaitGroup, &wg) wg.Add(1) // channel acceptor - // go dispatchChannelAcceptor(ctx, conn, client) + go dispatchChannelAcceptor(ctx, conn, client) - // htlc event subscriber, reports on incoming htlc events - router := routerrpc.NewRouterClient(conn) - stream, err := router.SubscribeHtlcEvents(ctx, &routerrpc.SubscribeHtlcEventsRequest{}) - if err != nil { - return - } + // htlc acceptor + go dispatchHTLCAcceptor(ctx, conn, client) - go func() { - err := processHtlcEvents(stream) - if err != nil { - log.Error("htlc events error", - "err", err) - } - }() + // // htlc event subscriber, reports on incoming htlc events + // router := routerrpc.NewRouterClient(conn) + // stream, err := router.SubscribeHtlcEvents(ctx, &routerrpc.SubscribeHtlcEventsRequest{}) + // if err != nil { + // return + // } - // interceptor, decide whether to accept or reject - interceptor, err := router.HtlcInterceptor(ctx) - if err != nil { - return - } + // go func() { + // err := processHtlcEvents(stream) + // if err != nil { + // log.Error("htlc events error", + // "err", err) + // } + // }() - log.Info("HTLC Interceptor registered") + // // interceptor, decide whether to accept or reject + // interceptor, err := router.HtlcInterceptor(ctx) + // if err != nil { + // return + // } - go func() { - err := processInterceptor(interceptor) - if err != nil { - log.Error("interceptor error", - "err", err) - } - }() + // log.Info("HTLC Interceptor registered") + + // go func() { + // err := processInterceptor(interceptor) + // if err != nil { + // log.Error("interceptor error", + // "err", err) + // } + // }() wg.Wait() From f55b101151da02e8daa7514e865dcdb88f142737 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 8 Jul 2022 12:38:18 +0200 Subject: [PATCH 5/8] clean --- htlcInterceptor.go | 12 +++++++----- main.go | 31 ------------------------------- 2 files changed, 7 insertions(+), 36 deletions(-) diff --git a/htlcInterceptor.go b/htlcInterceptor.go index e7c4d8f..648c523 100644 --- a/htlcInterceptor.go +++ b/htlcInterceptor.go @@ -11,15 +11,16 @@ import ( ) func dispatchHTLCAcceptor(ctx context.Context, conn *grpc.ClientConn, client lnrpc.LightningClient) { - // htlc event subscriber, reports on incoming htlc events router := routerrpc.NewRouterClient(conn) + + // htlc event subscriber, reports on incoming htlc events stream, err := router.SubscribeHtlcEvents(ctx, &routerrpc.SubscribeHtlcEventsRequest{}) if err != nil { return } go func() { - err := processHtlcEvents(stream) + err := logHtlcEvents(stream) if err != nil { log.Error("htlc events error", "err", err) @@ -33,7 +34,7 @@ func dispatchHTLCAcceptor(ctx context.Context, conn *grpc.ClientConn, client lnr } go func() { - err := processInterceptor(interceptor) + err := interceptHtlcEvents(interceptor) if err != nil { log.Error("interceptor error", "err", err) @@ -43,13 +44,14 @@ func dispatchHTLCAcceptor(ctx context.Context, conn *grpc.ClientConn, client lnr log.Info("Listening for incoming HTLCs") } -func processHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error { +func logHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error { for { event, err := stream.Recv() if err != nil { return err } + // we only care about HTLC forward events if event.EventType != routerrpc.HtlcEvent_FORWARD { continue } @@ -71,7 +73,7 @@ func processHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error } } -func processInterceptor(interceptor routerrpc.Router_HtlcInterceptorClient) error { +func interceptHtlcEvents(interceptor routerrpc.Router_HtlcInterceptorClient) error { for { event, err := interceptor.Recv() if err != nil { diff --git a/main.go b/main.go index bce388d..245d028 100644 --- a/main.go +++ b/main.go @@ -76,37 +76,6 @@ func main() { // htlc acceptor go dispatchHTLCAcceptor(ctx, conn, client) - // // htlc event subscriber, reports on incoming htlc events - // router := routerrpc.NewRouterClient(conn) - // stream, err := router.SubscribeHtlcEvents(ctx, &routerrpc.SubscribeHtlcEventsRequest{}) - // if err != nil { - // return - // } - - // go func() { - // err := processHtlcEvents(stream) - // if err != nil { - // log.Error("htlc events error", - // "err", err) - // } - // }() - - // // interceptor, decide whether to accept or reject - // interceptor, err := router.HtlcInterceptor(ctx) - // if err != nil { - // return - // } - - // log.Info("HTLC Interceptor registered") - - // go func() { - // err := processInterceptor(interceptor) - // if err != nil { - // log.Error("interceptor error", - // "err", err) - // } - // }() - wg.Wait() } From 6e4ae7f61aafbb5c34a05d6f8ca80698ce8df992 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 8 Jul 2022 13:23:39 +0200 Subject: [PATCH 6/8] cleanup --- channelAcceptor.go | 3 ++- config.go | 1 + htlcInterceptor.go | 16 ++++++++-------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/channelAcceptor.go b/channelAcceptor.go index 96c2acf..5fb7cea 100644 --- a/channelAcceptor.go +++ b/channelAcceptor.go @@ -2,6 +2,7 @@ package main import ( "context" + "encoding/binary" "encoding/hex" "sync" @@ -49,7 +50,7 @@ func dispatchChannelAcceptor(ctx context.Context, conn *grpc.ClientConn, client res := lnrpc.ChannelAcceptResponse{} if accept { - log.Infof("✅ [%s mode] Allow channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) + log.Infof("✅ [%s mode] Allow channel from %s (chan_id: %d)", Configuration.Mode, trimPubKey(req.NodePubkey), binary.BigEndian.Uint64(req.PendingChanId)) res = lnrpc.ChannelAcceptResponse{Accept: true, PendingChanId: req.PendingChanId, CsvDelay: req.CsvDelay, diff --git a/config.go b/config.go index 213d618..07d0bce 100644 --- a/config.go +++ b/config.go @@ -15,6 +15,7 @@ var Configuration = struct { Whitelist []string `yaml:"whitelist"` Blacklist []string `yaml:"blacklist"` RejectMessage string `yaml:"reject_message"` + Workers int `yaml:"workers"` }{} func init() { diff --git a/htlcInterceptor.go b/htlcInterceptor.go index 648c523..533bcc4 100644 --- a/htlcInterceptor.go +++ b/htlcInterceptor.go @@ -58,16 +58,16 @@ func logHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error { switch event.Event.(type) { case *routerrpc.HtlcEvent_SettleEvent: - log.Infof("HTLC SettleEvent (chan_id:%d htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) + log.Infof("HTLC SettleEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) case *routerrpc.HtlcEvent_ForwardFailEvent: - log.Infof("HTLC ForwardFailEvent (chan_id:%d htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) + log.Infof("HTLC ForwardFailEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) case *routerrpc.HtlcEvent_ForwardEvent: - log.Infof("HTLC ForwardEvent (chan_id:%d htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) + log.Infof("HTLC ForwardEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) case *routerrpc.HtlcEvent_LinkFailEvent: - log.Infof("HTLC LinkFailEvent (chan_id:%d htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) + log.Infof("HTLC LinkFailEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) } } @@ -81,9 +81,9 @@ func interceptHtlcEvents(interceptor routerrpc.Router_HtlcInterceptorClient) err } // decision for routing - log.Infof("Received HTLC. Making random 50/50 decision...") + log.Infof("Received HTLC. Making random decision...") accept := true - if rand.Intn(2) == 0 { + if rand.Intn(10) < 8 { accept = false } @@ -92,10 +92,10 @@ func interceptHtlcEvents(interceptor routerrpc.Router_HtlcInterceptorClient) err } if accept { - log.Infof("✅ Accept HTLC (%d sat, %s)", event.IncomingAmountMsat/1000, event.IncomingCircuitKey.String()) + log.Infof("✅ Accept HTLC (%d sat, htlc_id:%d, chan_id:%d->%d)", event.IncomingAmountMsat/1000, event.IncomingCircuitKey.HtlcId, event.IncomingCircuitKey.ChanId, event.OutgoingRequestedChanId) response.Action = routerrpc.ResolveHoldForwardAction_RESUME } else { - log.Infof("❌ Reject HTLC (%d sat, %s)", event.IncomingAmountMsat/1000, event.IncomingCircuitKey.String()) + log.Infof("❌ Reject HTLC (%d sat, htlc_id:%d, chan_id:%d->%d)", event.IncomingAmountMsat/1000, event.IncomingCircuitKey.HtlcId, event.IncomingCircuitKey.ChanId, event.OutgoingRequestedChanId) response.Action = routerrpc.ResolveHoldForwardAction_FAIL } From e1d1a0d356f65c2287673f222fbd707971703041 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 8 Jul 2022 15:04:39 +0200 Subject: [PATCH 7/8] clean up --- channelAcceptor.go | 41 ++++++--- config.go | 56 ++++++++---- config.yaml.example | 30 +++++-- htlcInterceptor.go | 215 +++++++++++++++++++++++++++++++++++++------- main.go | 19 ++-- 5 files changed, 285 insertions(+), 76 deletions(-) diff --git a/channelAcceptor.go b/channelAcceptor.go index 5fb7cea..5656eb5 100644 --- a/channelAcceptor.go +++ b/channelAcceptor.go @@ -4,14 +4,16 @@ import ( "context" "encoding/binary" "encoding/hex" + "fmt" "sync" "github.com/lightningnetwork/lnd/lnrpc" log "github.com/sirupsen/logrus" - "google.golang.org/grpc" ) -func dispatchChannelAcceptor(ctx context.Context, conn *grpc.ClientConn, client lnrpc.LightningClient) { +func dispatchChannelAcceptor(ctx context.Context) { + client := ctx.Value(clientKey).(lnrpc.LightningClient) + // wait group for channel acceptor defer ctx.Value(ctxKeyWaitGroup).(*sync.WaitGroup).Done() // get the lnd grpc connection @@ -26,21 +28,33 @@ func dispatchChannelAcceptor(ctx context.Context, conn *grpc.ClientConn, client if err != nil { log.Errorf(err.Error()) } - log.Infof("New channel request from %s", hex.EncodeToString(req.NodePubkey)) + + // print the incoming channel request + alias, err := getNodeAlias(ctx, hex.EncodeToString(req.NodePubkey)) + if err != nil { + log.Errorf(err.Error()) + } + var node_info_string string + if alias != "" { + node_info_string = fmt.Sprintf("%s (%s)", alias, hex.EncodeToString(req.NodePubkey)) + } else { + node_info_string = hex.EncodeToString(req.NodePubkey) + } + log.Debugf("New channel request from %s", node_info_string) var accept bool - if Configuration.Mode == "whitelist" { + if Configuration.ChannelMode == "whitelist" { accept = false - for _, pubkey := range Configuration.Whitelist { + for _, pubkey := range Configuration.ChannelWhitelist { if hex.EncodeToString(req.NodePubkey) == pubkey { accept = true break } } - } else if Configuration.Mode == "blacklist" { + } else if Configuration.ChannelMode == "blacklist" { accept = true - for _, pubkey := range Configuration.Blacklist { + for _, pubkey := range Configuration.ChannelBlacklist { if hex.EncodeToString(req.NodePubkey) == pubkey { accept = false break @@ -48,9 +62,16 @@ func dispatchChannelAcceptor(ctx context.Context, conn *grpc.ClientConn, client } } + var channel_info_string string + if alias != "" { + channel_info_string = fmt.Sprintf("from %s (%s, %d sat, chan_id:%d)", alias, trimPubKey(req.NodePubkey), req.FundingAmt, binary.BigEndian.Uint64(req.PendingChanId)) + } else { + channel_info_string = fmt.Sprintf("from %s (%d sat, chan_id:%d)", trimPubKey(req.NodePubkey), req.FundingAmt, binary.BigEndian.Uint64(req.PendingChanId)) + } + res := lnrpc.ChannelAcceptResponse{} if accept { - log.Infof("✅ [%s mode] Allow channel from %s (chan_id: %d)", Configuration.Mode, trimPubKey(req.NodePubkey), binary.BigEndian.Uint64(req.PendingChanId)) + log.Infof("✅ [channel-mode %s] Allow channel %s", Configuration.ChannelMode, channel_info_string) res = lnrpc.ChannelAcceptResponse{Accept: true, PendingChanId: req.PendingChanId, CsvDelay: req.CsvDelay, @@ -61,9 +82,9 @@ func dispatchChannelAcceptor(ctx context.Context, conn *grpc.ClientConn, client } } else { - log.Infof("❌ [%s mode] Reject channel from %s", Configuration.Mode, trimPubKey(req.NodePubkey)) + log.Infof("❌ [channel-mode %s] Reject channel %s", Configuration.ChannelMode, channel_info_string) res = lnrpc.ChannelAcceptResponse{Accept: false, - Error: Configuration.RejectMessage} + Error: Configuration.ChannelRejectMessage} } err = acceptClient.Send(&res) if err != nil { diff --git a/config.go b/config.go index 07d0bce..47cd2d8 100644 --- a/config.go +++ b/config.go @@ -8,14 +8,17 @@ import ( ) var Configuration = struct { - Mode string `yaml:"mode"` - Host string `yaml:"host"` - MacaroonPath string `yaml:"macaroon_path"` - TLSPath string `yaml:"tls_path"` - Whitelist []string `yaml:"whitelist"` - Blacklist []string `yaml:"blacklist"` - RejectMessage string `yaml:"reject_message"` - Workers int `yaml:"workers"` + ChannelMode string `yaml:"channel-mode"` + Host string `yaml:"host"` + MacaroonPath string `yaml:"macaroon_path"` + TLSPath string `yaml:"tls-path"` + Debug bool `yaml:"debug"` + ChannelWhitelist []string `yaml:"channel-whitelist"` + ChannelBlacklist []string `yaml:"channel-blacklist"` + ChannelRejectMessage string `yaml:"channel-reject-message"` + ForwardMode string `yaml:"forward-mode"` + ForwardWhitelist []string `yaml:"forward-whitelist"` + ForwardBlacklist []string `yaml:"forward-blacklist"` }{} func init() { @@ -27,20 +30,39 @@ func init() { } func checkConfig() { + setLogger(Configuration.Debug) + welcome() + if Configuration.Host == "" { panic(fmt.Errorf("no host specified in config.yaml")) } - - if len(Configuration.Whitelist) == 0 { - panic(fmt.Errorf("no accepted pubkeys specified in config.yaml")) + if Configuration.MacaroonPath == "" { + panic(fmt.Errorf("no macaroon path specified in config.yaml")) + } + if Configuration.TLSPath == "" { + panic(fmt.Errorf("no tls path specified in config.yaml")) } - if len(Configuration.RejectMessage) > 500 { - log.Warnf("reject message is too long. Trimming to 500 characters.") - Configuration.RejectMessage = Configuration.RejectMessage[:500] + if len(Configuration.ChannelRejectMessage) > 500 { + log.Warnf("channel reject message is too long. Trimming to 500 characters.") + Configuration.ChannelRejectMessage = Configuration.ChannelRejectMessage[:500] } - if len(Configuration.Mode) == 0 { - Configuration.Mode = "blacklist" + + if len(Configuration.ChannelMode) == 0 { + Configuration.ChannelMode = "blacklist" } - log.Infof("Running in %s mode", Configuration.Mode) + if Configuration.ChannelMode != "whitelist" && Configuration.ChannelMode != "blacklist" { + panic(fmt.Errorf("channel mode must be either whitelist or blacklist")) + } + + log.Infof("Channel acceptor running in %s mode", Configuration.ForwardMode) + + if len(Configuration.ForwardMode) == 0 { + Configuration.ForwardMode = "blacklist" + } + if Configuration.ForwardMode != "whitelist" && Configuration.ForwardMode != "blacklist" { + panic(fmt.Errorf("channel mode must be either whitelist or blacklist")) + } + + log.Infof("HTLC forwarder running in %s mode", Configuration.ForwardMode) } diff --git a/config.yaml.example b/config.yaml.example index 7a1f047..fc5b587 100644 --- a/config.yaml.example +++ b/config.yaml.example @@ -1,17 +1,31 @@ -# Mode can either be "blacklist" or "whitelist" -mode: "blacklist" - # Credentials for your node host: "127.0.0.1:10009" macaroon_path: "/home/bitcoin/.lnd/data/chain/bitcoin/mainnet/admin.macaroon" -tls_path: "/home/bitcoin/.lnd/tls.cert" +tls-path: "/home/bitcoin/.lnd/tls.cert" + +# ----- Channel accept ----- + +# Mode can either be "blacklist" or "whitelist" +channel-mode: "blacklist" # This error message will be sent to the other party upon a reject -reject_message: "Contact me at user@email.com" +channel-reject-message: "Contact me at user@email.com" # List of nodes to whitelist or blacklist -whitelist: +channel-whitelist: - "03de70865239e99460041e127647b37101b9eb335b3c22de95c944671f0dabc2d0" - "0307299a290529c5ccb3a5e3bd2eb504daf64cc65c6d65b582c01cbd7e5ede14b6" -blacklist: - - "02853f9c1d15d479b433039885373b681683b84bb73e86dff861bee6697c17c1de" \ No newline at end of file +channel-blacklist: + - "02853f9c1d15d479b433039885373b681683b84bb73e86dff861bee6697c17c1de" + +# ----- HTLC forwarding ----- + +# Mode can either be "blacklist" or "whitelist" +forward-mode: "whitelist" + +# List of channel IDs to whitelist or blacklist +forward-whitelist: + - "229797930270721" +forward-blacklist: + - "131941395398657" + - "195713069809665" \ No newline at end of file diff --git a/htlcInterceptor.go b/htlcInterceptor.go index 533bcc4..95c66be 100644 --- a/htlcInterceptor.go +++ b/htlcInterceptor.go @@ -2,15 +2,42 @@ package main import ( "context" - "math/rand" + "errors" + "fmt" + "strconv" + "time" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" + "github.com/lightningnetwork/lnd/routing/route" log "github.com/sirupsen/logrus" "google.golang.org/grpc" ) -func dispatchHTLCAcceptor(ctx context.Context, conn *grpc.ClientConn, client lnrpc.LightningClient) { +// type circuitKey struct { +// channel uint64 +// htlc uint64 +// } + +// type interceptEvent struct { +// circuitKey +// valueMsat int64 +// resume chan bool +// } +// type htlcAcceptor struct { +// interceptChan chan interceptEvent +// resolveChan chan circuitKey +// } + +// func newHtlcAcceptor() *htlcAcceptor { +// return &htlcAcceptor{ +// interceptChan: make(chan interceptEvent), +// resolveChan: make(chan circuitKey), +// } +// } + +func dispatchHTLCAcceptor(ctx context.Context) { + conn := ctx.Value(connKey).(*grpc.ClientConn) router := routerrpc.NewRouterClient(conn) // htlc event subscriber, reports on incoming htlc events @@ -20,7 +47,7 @@ func dispatchHTLCAcceptor(ctx context.Context, conn *grpc.ClientConn, client lnr } go func() { - err := logHtlcEvents(stream) + err := logHtlcEvents(ctx, stream) if err != nil { log.Error("htlc events error", "err", err) @@ -34,7 +61,7 @@ func dispatchHTLCAcceptor(ctx context.Context, conn *grpc.ClientConn, client lnr } go func() { - err := interceptHtlcEvents(interceptor) + err := interceptHtlcEvents(ctx, interceptor) if err != nil { log.Error("interceptor error", "err", err) @@ -44,7 +71,7 @@ func dispatchHTLCAcceptor(ctx context.Context, conn *grpc.ClientConn, client lnr log.Info("Listening for incoming HTLCs") } -func logHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error { +func logHtlcEvents(ctx context.Context, stream routerrpc.Router_SubscribeHtlcEventsClient) error { for { event, err := stream.Recv() if err != nil { @@ -58,50 +85,174 @@ func logHtlcEvents(stream routerrpc.Router_SubscribeHtlcEventsClient) error { switch event.Event.(type) { case *routerrpc.HtlcEvent_SettleEvent: - log.Infof("HTLC SettleEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) + log.Debugf("HTLC SettleEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) case *routerrpc.HtlcEvent_ForwardFailEvent: - log.Infof("HTLC ForwardFailEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) + log.Debugf("HTLC ForwardFailEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) case *routerrpc.HtlcEvent_ForwardEvent: - log.Infof("HTLC ForwardEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) + log.Debugf("HTLC ForwardEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) case *routerrpc.HtlcEvent_LinkFailEvent: - log.Infof("HTLC LinkFailEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) + log.Debugf("HTLC LinkFailEvent (chan_id:%d, htlc_id:%d)", event.IncomingChannelId, event.IncomingHtlcId) } } } -func interceptHtlcEvents(interceptor routerrpc.Router_HtlcInterceptorClient) error { +func interceptHtlcEvents(ctx context.Context, interceptor routerrpc.Router_HtlcInterceptorClient) error { for { event, err := interceptor.Recv() if err != nil { return err } + go func() { + // decision for routing + decision_chan := make(chan bool, 1) + go htlcInterceptDecision(ctx, event, decision_chan) - // decision for routing - log.Infof("Received HTLC. Making random decision...") - accept := true - if rand.Intn(10) < 8 { - accept = false - } + channelEdge, err := getPubKeyFromChannel(ctx, event.IncomingCircuitKey.ChanId) + if err != nil { + log.Error("Error getting pubkey for channel %d", event.IncomingCircuitKey.ChanId) + } + alias, err := getNodeAlias(ctx, channelEdge.node1Pub.String()) + if err != nil { + log.Errorf(err.Error()) + } - response := &routerrpc.ForwardHtlcInterceptResponse{ - IncomingCircuitKey: event.IncomingCircuitKey, - } - - if accept { - log.Infof("✅ Accept HTLC (%d sat, htlc_id:%d, chan_id:%d->%d)", event.IncomingAmountMsat/1000, event.IncomingCircuitKey.HtlcId, event.IncomingCircuitKey.ChanId, event.OutgoingRequestedChanId) - response.Action = routerrpc.ResolveHoldForwardAction_RESUME - } else { - log.Infof("❌ Reject HTLC (%d sat, htlc_id:%d, chan_id:%d->%d)", event.IncomingAmountMsat/1000, event.IncomingCircuitKey.HtlcId, event.IncomingCircuitKey.ChanId, event.OutgoingRequestedChanId) - response.Action = routerrpc.ResolveHoldForwardAction_FAIL - } - - err = interceptor.Send(response) - if err != nil { - return err - } + var forward_info_string string + if alias != "" { + forward_info_string = fmt.Sprintf("from %s (%d sat, htlc_id:%d, chan_id:%d->%d)", alias, event.IncomingAmountMsat/1000, event.IncomingCircuitKey.HtlcId, event.IncomingCircuitKey.ChanId, event.OutgoingRequestedChanId) + } else { + forward_info_string = fmt.Sprintf("(%d sat, htlc_id:%d, chan_id:%d->%d)", event.IncomingAmountMsat/1000, event.IncomingCircuitKey.HtlcId, event.IncomingCircuitKey.ChanId, event.OutgoingRequestedChanId) + } + response := &routerrpc.ForwardHtlcInterceptResponse{ + IncomingCircuitKey: event.IncomingCircuitKey, + } + if <-decision_chan { + log.Infof("✅ [forward-mode %s] Accept HTLC %s", Configuration.ForwardMode, forward_info_string) + response.Action = routerrpc.ResolveHoldForwardAction_RESUME + } else { + log.Infof("❌ [forward-mode %s] Reject HTLC %s", Configuration.ForwardMode, forward_info_string) + response.Action = routerrpc.ResolveHoldForwardAction_FAIL + } + err = interceptor.Send(response) + if err != nil { + return + } + }() } } + +func htlcInterceptDecision(ctx context.Context, event *routerrpc.ForwardHtlcInterceptRequest, decision_chan chan bool) { + var accept bool + + if Configuration.ForwardMode == "whitelist" { + accept = false + for _, channel_id := range Configuration.ForwardWhitelist { + chan_id_int, err := strconv.ParseUint(channel_id, 10, 64) + if err != nil { + log.Error("Error parsing channel id %s", channel_id) + break + } + if event.IncomingCircuitKey.ChanId == chan_id_int { + accept = true + break + } + } + } else if Configuration.ForwardMode == "blacklist" { + accept = true + for _, channel_id := range Configuration.ForwardBlacklist { + chan_id_int, err := strconv.ParseUint(channel_id, 10, 64) + if err != nil { + log.Error("Error parsing channel id %s", channel_id) + break + } + if event.IncomingCircuitKey.ChanId == chan_id_int { + accept = false + break + } + } + } + decision_chan <- accept +} + +// Heavily inspired by by Joost Jager's circuitbreaker +func getNodeAlias(ctx context.Context, pubkey string) (string, error) { + client := ctx.Value(clientKey).(lnrpc.LightningClient) + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + info, err := client.GetNodeInfo(ctx, &lnrpc.NodeInfoRequest{ + PubKey: pubkey, + }) + if err != nil { + return "", err + } + + if info.Node == nil { + return "", errors.New("node info not available") + } + + return info.Node.Alias, nil +} + +type channelEdge struct { + node1Pub, node2Pub route.Vertex +} + +func getPubKeyFromChannel(ctx context.Context, chan_id uint64) (*channelEdge, error) { + client := ctx.Value(clientKey).(lnrpc.LightningClient) + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + info, err := client.GetChanInfo(ctx, &lnrpc.ChanInfoRequest{ + ChanId: chan_id, + }) + if err != nil { + return nil, err + } + + node1Pub, err := route.NewVertexFromStr(info.Node1Pub) + if err != nil { + return nil, err + } + + node2Pub, err := route.NewVertexFromStr(info.Node2Pub) + if err != nil { + return nil, err + } + + return &channelEdge{ + node1Pub: node1Pub, + node2Pub: node2Pub, + }, nil +} + +// func getPubKey(channel uint64) (route.Vertex, error) { +// pubkey, ok := p.pubkeyMap[channel] +// if ok { +// return pubkey, nil +// } + +// edge, err := p.client.getChanInfo(channel) +// if err != nil { +// return route.Vertex{}, err +// } + +// var remotePubkey route.Vertex +// switch { +// case edge.node1Pub == p.identity: +// remotePubkey = edge.node2Pub + +// case edge.node2Pub == p.identity: +// remotePubkey = edge.node1Pub + +// default: +// return route.Vertex{}, errors.New("identity not found in chan info") +// } + +// p.pubkeyMap[channel] = remotePubkey + +// return remotePubkey, nil +// } diff --git a/main.go b/main.go index 245d028..1da3470 100644 --- a/main.go +++ b/main.go @@ -2,8 +2,6 @@ package main import ( "context" - "encoding/hex" - "fmt" "io/ioutil" "sync" @@ -22,6 +20,11 @@ const ( ctxKeyWaitGroup key = iota ) +type ContextKey string + +var connKey ContextKey = "connKey" +var clientKey ContextKey = "clientKey" + // gets the lnd grpc connection func getClientConnection(ctx context.Context) (*grpc.ClientConn, error) { creds, err := credentials.NewClientTLSFromFile(Configuration.TLSPath, "") @@ -54,10 +57,6 @@ func getClientConnection(ctx context.Context) (*grpc.ClientConn, error) { } -func trimPubKey(pubkey []byte) string { - return fmt.Sprintf("%s...%s", hex.EncodeToString(pubkey)[:6], hex.EncodeToString(pubkey)[len(hex.EncodeToString(pubkey))-6:]) -} - func main() { ctx := context.Background() conn, err := getClientConnection(ctx) @@ -70,12 +69,14 @@ func main() { ctx = context.WithValue(ctx, ctxKeyWaitGroup, &wg) wg.Add(1) + ctx = context.WithValue(ctx, clientKey, client) + ctx = context.WithValue(ctx, connKey, conn) + // channel acceptor - go dispatchChannelAcceptor(ctx, conn, client) + go dispatchChannelAcceptor(ctx) // htlc acceptor - go dispatchHTLCAcceptor(ctx, conn, client) + go dispatchHTLCAcceptor(ctx) wg.Wait() - } From cf7718bdda623b3b9d0c19c3561af9dfe597a224 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 8 Jul 2022 15:05:08 +0200 Subject: [PATCH 8/8] clean --- htlcInterceptor.go | 50 ---------------------------------------------- 1 file changed, 50 deletions(-) diff --git a/htlcInterceptor.go b/htlcInterceptor.go index 95c66be..dae7a51 100644 --- a/htlcInterceptor.go +++ b/htlcInterceptor.go @@ -14,28 +14,6 @@ import ( "google.golang.org/grpc" ) -// type circuitKey struct { -// channel uint64 -// htlc uint64 -// } - -// type interceptEvent struct { -// circuitKey -// valueMsat int64 -// resume chan bool -// } -// type htlcAcceptor struct { -// interceptChan chan interceptEvent -// resolveChan chan circuitKey -// } - -// func newHtlcAcceptor() *htlcAcceptor { -// return &htlcAcceptor{ -// interceptChan: make(chan interceptEvent), -// resolveChan: make(chan circuitKey), -// } -// } - func dispatchHTLCAcceptor(ctx context.Context) { conn := ctx.Value(connKey).(*grpc.ClientConn) router := routerrpc.NewRouterClient(conn) @@ -228,31 +206,3 @@ func getPubKeyFromChannel(ctx context.Context, chan_id uint64) (*channelEdge, er node2Pub: node2Pub, }, nil } - -// func getPubKey(channel uint64) (route.Vertex, error) { -// pubkey, ok := p.pubkeyMap[channel] -// if ok { -// return pubkey, nil -// } - -// edge, err := p.client.getChanInfo(channel) -// if err != nil { -// return route.Vertex{}, err -// } - -// var remotePubkey route.Vertex -// switch { -// case edge.node1Pub == p.identity: -// remotePubkey = edge.node2Pub - -// case edge.node2Pub == p.identity: -// remotePubkey = edge.node1Pub - -// default: -// return route.Vertex{}, errors.New("identity not found in chan info") -// } - -// p.pubkeyMap[channel] = remotePubkey - -// return remotePubkey, nil -// }