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 (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -741,17 +742,6 @@ func (r *RouterBackend) extractIntentFromSendRequest(
|
||||
|
||||
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.
|
||||
features, err := UnmarshalFeatures(rpcPayReq.DestFeatures)
|
||||
if err != nil {
|
||||
@ -766,14 +756,83 @@ func (r *RouterBackend) extractIntentFromSendRequest(
|
||||
}
|
||||
}
|
||||
|
||||
// If the payment addresses is specified, then we'll also
|
||||
// populate that now as well.
|
||||
// If this is an AMP payment, we must generate the initial
|
||||
// randomness.
|
||||
if rpcPayReq.Amp {
|
||||
// If no destination features were specified, we set
|
||||
// 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
|
||||
|
||||
// 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
|
||||
}
|
||||
|
@ -1806,14 +1806,33 @@ type AMPOptions struct {
|
||||
// SetPaymentHash sets the given hash as the payment's overall hash. This
|
||||
// should only be used for non-AMP payments.
|
||||
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
|
||||
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
|
||||
// payment. For non-AMP payments this will be the payment hash, for AMP
|
||||
// payments this will be the used SetID.
|
||||
func (l *LightningPayment) Identifier() [32]byte {
|
||||
if l.amp != nil {
|
||||
return l.amp.SetID
|
||||
}
|
||||
|
||||
return *l.paymentHash
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user