Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add routing hints for private nodes in LND #1186

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 66 additions & 1 deletion lnclient/lnd/lnd.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,12 +468,23 @@ func (svc *LNDService) MakeInvoice(ctx context.Context, amount int64, descriptio
}
}

isPrivate := !hasPublicChannels

var hints []*lnrpc.RouteHint
if isPrivate {
hints, err = svc.getRoutingHints(ctx)
if err != nil {
return nil, err
}
}

addInvoiceRequest := &lnrpc.Invoice{
ValueMsat: amount,
Memo: description,
DescriptionHash: descriptionHashBytes,
Expiry: expiry,
Private: !hasPublicChannels, // use private channel hints in the invoice
RouteHints: hints,
Private: isPrivate, // use private channel hints in the invoice
}

resp, err := svc.client.AddInvoice(ctx, addInvoiceRequest)
Expand All @@ -492,6 +503,60 @@ func (svc *LNDService) MakeInvoice(ctx context.Context, amount int64, descriptio
return transaction, nil
}

func (svc *LNDService) getRoutingHints(ctx context.Context) (hints []*lnrpc.RouteHint, err error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you take inspiration from anywhere for this code? I think there are quite a few issues here.

Can you please check the LND codebase and some other lightning wallets (e.g. https://github1s.com/ZeusLN/zeus/blob/HEAD/lndmobile/index.ts#L632-L633)

I think there's no limit right now, right? we need to limit it to 3 (the "best" options based on incoming liquidity and fees)

Can you also check if we have 1 peer the route hint is exactly the same as is when not using this code. We need to make very sure we don't break this code otherwise no-one with private channels will be able to receive.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure the above code I linked is used. I've also asked Zeus if they can give us any recommendations.

channelsRes, err := svc.client.ListChannels(ctx, &lnrpc.ListChannelsRequest{
PrivateOnly: true,
})
if err != nil {
return nil, err
}

processedPeers := make(map[string]struct{})
for _, channel := range channelsRes.Channels {
if _, ok := processedPeers[channel.RemotePubkey]; ok {
continue
}

chanInfo, err := svc.client.GetChanInfo(ctx, &lnrpc.ChanInfoRequest{
ChanId: channel.ChanId,
})
if err != nil {
logger.Logger.WithFields(logrus.Fields{
"channel_id": channel.ChanId,
}).WithError(err).Error("Unable to add routing hint")
continue
}

remotePolicy := chanInfo.Node2Policy
Copy link
Contributor

Choose a reason for hiding this comment

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

Node2 is not always the counterparty is it?

if remotePolicy == nil {
continue
}

feeBaseMsat := uint32(remotePolicy.FeeBaseMsat)
proportionalFee := uint32(remotePolicy.FeeRateMilliMsat)
cltvExpiryDelta := remotePolicy.TimeLockDelta

logger.Logger.WithFields(logrus.Fields{
"remote_pubkey": channel.RemotePubkey,
}).Info("Adding routing hint")

hint := &lnrpc.RouteHint{
HopHints: []*lnrpc.HopHint{
{
NodeId: channel.RemotePubkey,
ChanId: chanInfo.ChannelId,
FeeBaseMsat: feeBaseMsat,
FeeProportionalMillionths: proportionalFee,
CltvExpiryDelta: cltvExpiryDelta,
},
},
}
hints = append(hints, hint)
processedPeers[channel.RemotePubkey] = struct{}{}
}
return hints, nil
}

func (svc *LNDService) LookupInvoice(ctx context.Context, paymentHash string) (transaction *lnclient.Transaction, err error) {
paymentHashBytes, err := hex.DecodeString(paymentHash)
if err != nil || len(paymentHashBytes) != 32 {
Expand Down
Loading