routerrpc+routing: set AMP options for payments specified as AMP in SendPayment
This commit is contained in:
parent
8f57dcf28f
commit
c4fc72d573
@ -2,6 +2,7 @@ package routerrpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -741,17 +742,6 @@ func (r *RouterBackend) extractIntentFromSendRequest(
|
|||||||
|
|
||||||
payIntent.Amount = reqAmt
|
payIntent.Amount = reqAmt
|
||||||
|
|
||||||
// Payment hash.
|
|
||||||
paymentHash, err := lntypes.MakeHash(rpcPayReq.PaymentHash)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = payIntent.SetPaymentHash(paymentHash)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse destination feature bits.
|
// Parse destination feature bits.
|
||||||
features, err := UnmarshalFeatures(rpcPayReq.DestFeatures)
|
features, err := UnmarshalFeatures(rpcPayReq.DestFeatures)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -766,13 +756,82 @@ func (r *RouterBackend) extractIntentFromSendRequest(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the payment addresses is specified, then we'll also
|
// If this is an AMP payment, we must generate the initial
|
||||||
// populate that now as well.
|
// randomness.
|
||||||
if len(rpcPayReq.PaymentAddr) != 0 {
|
if rpcPayReq.Amp {
|
||||||
var payAddr [32]byte
|
// If no destination features were specified, we set
|
||||||
copy(payAddr[:], rpcPayReq.PaymentAddr)
|
// those necessary for AMP payments.
|
||||||
|
if features == nil {
|
||||||
|
ampFeatures := []lnrpc.FeatureBit{
|
||||||
|
lnrpc.FeatureBit_TLV_ONION_OPT,
|
||||||
|
lnrpc.FeatureBit_PAYMENT_ADDR_OPT,
|
||||||
|
lnrpc.FeatureBit_MPP_OPT,
|
||||||
|
lnrpc.FeatureBit_AMP_OPT,
|
||||||
|
}
|
||||||
|
|
||||||
|
features, err = UnmarshalFeatures(ampFeatures)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// First make sure the destination supports AMP.
|
||||||
|
if !features.HasFeature(lnwire.AMPOptional) {
|
||||||
|
return nil, fmt.Errorf("destination doesn't " +
|
||||||
|
"support AMP payments")
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no payment address is set, generate a random one.
|
||||||
|
var payAddr [32]byte
|
||||||
|
if len(rpcPayReq.PaymentAddr) == 0 {
|
||||||
|
_, err = rand.Read(payAddr[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
copy(payAddr[:], rpcPayReq.PaymentAddr)
|
||||||
|
}
|
||||||
payIntent.PaymentAddr = &payAddr
|
payIntent.PaymentAddr = &payAddr
|
||||||
|
|
||||||
|
// Generate random SetID and root share.
|
||||||
|
var setID [32]byte
|
||||||
|
_, err = rand.Read(setID[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var rootShare [32]byte
|
||||||
|
_, err = rand.Read(rootShare[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err := payIntent.SetAMP(&routing.AMPOptions{
|
||||||
|
SetID: setID,
|
||||||
|
RootShare: rootShare,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Payment hash.
|
||||||
|
paymentHash, err := lntypes.MakeHash(rpcPayReq.PaymentHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = payIntent.SetPaymentHash(paymentHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the payment addresses is specified, then we'll
|
||||||
|
// also populate that now as well.
|
||||||
|
if len(rpcPayReq.PaymentAddr) != 0 {
|
||||||
|
var payAddr [32]byte
|
||||||
|
copy(payAddr[:], rpcPayReq.PaymentAddr)
|
||||||
|
|
||||||
|
payIntent.PaymentAddr = &payAddr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
payIntent.DestFeatures = features
|
payIntent.DestFeatures = features
|
||||||
|
@ -1806,14 +1806,33 @@ type AMPOptions struct {
|
|||||||
// SetPaymentHash sets the given hash as the payment's overall hash. This
|
// SetPaymentHash sets the given hash as the payment's overall hash. This
|
||||||
// should only be used for non-AMP payments.
|
// should only be used for non-AMP payments.
|
||||||
func (l *LightningPayment) SetPaymentHash(hash lntypes.Hash) error {
|
func (l *LightningPayment) SetPaymentHash(hash lntypes.Hash) error {
|
||||||
|
if l.amp != nil {
|
||||||
|
return fmt.Errorf("cannot set payment hash for AMP payment")
|
||||||
|
}
|
||||||
|
|
||||||
l.paymentHash = &hash
|
l.paymentHash = &hash
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetAMP sets the given AMP options for the payment.
|
||||||
|
func (l *LightningPayment) SetAMP(amp *AMPOptions) error {
|
||||||
|
if l.paymentHash != nil {
|
||||||
|
return fmt.Errorf("cannot set amp options for payment " +
|
||||||
|
"with payment hash")
|
||||||
|
}
|
||||||
|
|
||||||
|
l.amp = amp
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Identifier returns a 32-byte slice that uniquely identifies this single
|
// Identifier returns a 32-byte slice that uniquely identifies this single
|
||||||
// payment. For non-AMP payments this will be the payment hash, for AMP
|
// payment. For non-AMP payments this will be the payment hash, for AMP
|
||||||
// payments this will be the used SetID.
|
// payments this will be the used SetID.
|
||||||
func (l *LightningPayment) Identifier() [32]byte {
|
func (l *LightningPayment) Identifier() [32]byte {
|
||||||
|
if l.amp != nil {
|
||||||
|
return l.amp.SetID
|
||||||
|
}
|
||||||
|
|
||||||
return *l.paymentHash
|
return *l.paymentHash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user