mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-07-02 19:44:03 +02:00
Merge pull request #8735 from ellemouton/rb-receives
[2/4] Route Blinding Receives: Receive and send to a single blinded path in an invoice.
This commit is contained in:
85
rpcserver.go
85
rpcserver.go
@ -75,6 +75,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/peernotifier"
|
||||
"github.com/lightningnetwork/lnd/record"
|
||||
"github.com/lightningnetwork/lnd/routing"
|
||||
"github.com/lightningnetwork/lnd/routing/blindedpath"
|
||||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
"github.com/lightningnetwork/lnd/rpcperms"
|
||||
"github.com/lightningnetwork/lnd/signal"
|
||||
@ -5104,6 +5105,7 @@ type rpcPaymentIntent struct {
|
||||
paymentAddr *[32]byte
|
||||
payReq []byte
|
||||
metadata []byte
|
||||
blindedPayment *routing.BlindedPayment
|
||||
|
||||
destCustomRecords record.CustomSet
|
||||
|
||||
@ -5239,6 +5241,32 @@ func (r *rpcServer) extractPaymentIntent(rpcPayReq *rpcPaymentRequest) (rpcPayme
|
||||
payIntent.paymentAddr = payReq.PaymentAddr
|
||||
payIntent.metadata = payReq.Metadata
|
||||
|
||||
if len(payReq.BlindedPaymentPaths) > 0 {
|
||||
// NOTE: Currently we only choose a single payment path.
|
||||
// This will be updated in a future PR to handle
|
||||
// multiple blinded payment paths.
|
||||
path := payReq.BlindedPaymentPaths[0]
|
||||
if len(path.Hops) == 0 {
|
||||
return payIntent, fmt.Errorf("a blinded " +
|
||||
"payment must have at least 1 hop")
|
||||
}
|
||||
|
||||
finalHop := path.Hops[len(path.Hops)-1]
|
||||
payIntent.blindedPayment =
|
||||
routerrpc.MarshalBlindedPayment(path)
|
||||
|
||||
// Replace the target node with the blinded public key
|
||||
// of the blinded path's final node.
|
||||
copy(
|
||||
payIntent.dest[:],
|
||||
finalHop.BlindedNodePub.SerializeCompressed(),
|
||||
)
|
||||
|
||||
if !payReq.BlindedPaymentPaths[0].Features.IsEmpty() {
|
||||
payIntent.destFeatures = path.Features.Clone()
|
||||
}
|
||||
}
|
||||
|
||||
if err := validateDest(payIntent.dest); err != nil {
|
||||
return payIntent, err
|
||||
}
|
||||
@ -5393,6 +5421,7 @@ func (r *rpcServer) dispatchPaymentIntent(
|
||||
DestFeatures: payIntent.destFeatures,
|
||||
PaymentAddr: payIntent.paymentAddr,
|
||||
Metadata: payIntent.metadata,
|
||||
BlindedPayment: payIntent.blindedPayment,
|
||||
|
||||
// Don't enable multi-part payments on the main rpc.
|
||||
// Users need to use routerrpc for that.
|
||||
@ -5737,6 +5766,13 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
|
||||
|
||||
defaultDelta := r.cfg.Bitcoin.TimeLockDelta
|
||||
|
||||
blindingRestrictions := &routing.BlindedPathRestrictions{
|
||||
MinDistanceFromIntroNode: r.server.cfg.Routing.BlindedPaths.
|
||||
MinNumRealHops,
|
||||
NumHops: r.server.cfg.Routing.BlindedPaths.NumHops,
|
||||
MaxNumPaths: r.server.cfg.Routing.BlindedPaths.MaxNumPaths,
|
||||
}
|
||||
|
||||
addInvoiceCfg := &invoicesrpc.AddInvoiceConfig{
|
||||
AddInvoice: r.server.invoices.AddInvoice,
|
||||
IsChannelActive: r.server.htlcSwitch.HasActiveLink,
|
||||
@ -5746,12 +5782,56 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
|
||||
ChanDB: r.server.chanStateDB,
|
||||
Graph: r.server.graphDB,
|
||||
GenInvoiceFeatures: func() *lnwire.FeatureVector {
|
||||
return r.server.featureMgr.Get(feature.SetInvoice)
|
||||
v := r.server.featureMgr.Get(feature.SetInvoice)
|
||||
|
||||
if invoice.Blind {
|
||||
// If an invoice includes blinded paths, then a
|
||||
// payment address is not required since we use
|
||||
// the PathID in the final hop's encrypted data
|
||||
// as equivalent to the payment address
|
||||
v.Unset(lnwire.PaymentAddrRequired)
|
||||
v.Set(lnwire.PaymentAddrOptional)
|
||||
|
||||
// The invoice payer will also need to
|
||||
// understand the new BOLT 11 tagged field
|
||||
// containing the blinded path, so we switch
|
||||
// the bit to required.
|
||||
v.Unset(lnwire.Bolt11BlindedPathsOptional)
|
||||
v.Set(lnwire.Bolt11BlindedPathsRequired)
|
||||
}
|
||||
|
||||
return v
|
||||
},
|
||||
GenAmpInvoiceFeatures: func() *lnwire.FeatureVector {
|
||||
return r.server.featureMgr.Get(feature.SetInvoiceAmp)
|
||||
},
|
||||
GetAlias: r.server.aliasMgr.GetPeerAlias,
|
||||
GetAlias: r.server.aliasMgr.GetPeerAlias,
|
||||
BestHeight: r.server.cc.BestBlockTracker.BestHeight,
|
||||
BlindedRoutePolicyIncrMultiplier: r.server.cfg.Routing.
|
||||
BlindedPaths.PolicyIncreaseMultiplier,
|
||||
BlindedRoutePolicyDecrMultiplier: r.server.cfg.Routing.
|
||||
BlindedPaths.PolicyDecreaseMultiplier,
|
||||
QueryBlindedRoutes: func(amt lnwire.MilliSatoshi) (
|
||||
[]*route.Route, error) {
|
||||
|
||||
return r.server.chanRouter.FindBlindedPaths(
|
||||
r.selfNode, amt,
|
||||
r.server.missionControl.GetProbability,
|
||||
blindingRestrictions,
|
||||
)
|
||||
},
|
||||
MinNumBlindedPathHops: r.server.cfg.Routing.BlindedPaths.
|
||||
NumHops,
|
||||
DefaultDummyHopPolicy: &blindedpath.BlindedHopPolicy{
|
||||
CLTVExpiryDelta: uint16(defaultDelta),
|
||||
FeeRate: uint32(r.server.cfg.Bitcoin.FeeRate),
|
||||
BaseFee: r.server.cfg.Bitcoin.BaseFee,
|
||||
MinHTLCMsat: r.server.cfg.Bitcoin.MinHTLCIn,
|
||||
|
||||
// MaxHTLCMsat will be calculated on the fly by using
|
||||
// the introduction node's channel's capacities.
|
||||
MaxHTLCMsat: 0,
|
||||
},
|
||||
}
|
||||
|
||||
value, err := lnrpc.UnmarshallAmt(invoice.Value, invoice.ValueMsat)
|
||||
@ -5774,6 +5854,7 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
|
||||
Private: invoice.Private,
|
||||
RouteHints: routeHints,
|
||||
Amp: invoice.IsAmp,
|
||||
Blind: invoice.Blind,
|
||||
}
|
||||
|
||||
if invoice.RPreimage != nil {
|
||||
|
Reference in New Issue
Block a user