mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-05 17:05:50 +02:00
channeldb: store hold invoice
This commit is contained in:
@@ -4,19 +4,20 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/netann"
|
||||
"github.com/lightningnetwork/lnd/zpay32"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/netann"
|
||||
"github.com/lightningnetwork/lnd/zpay32"
|
||||
)
|
||||
|
||||
// AddInvoiceConfig contains dependencies for invoice creation.
|
||||
@@ -61,9 +62,15 @@ type AddInvoiceData struct {
|
||||
Receipt []byte
|
||||
|
||||
// The preimage which will allow settling an incoming HTLC payable to
|
||||
// this preimage.
|
||||
// this preimage. If Preimage is set, Hash should be nil. If both
|
||||
// Preimage and Hash are nil, a random preimage is generated.
|
||||
Preimage *lntypes.Preimage
|
||||
|
||||
// The hash of the preimage. If Hash is set, Preimage should be nil.
|
||||
// This condition indicates that we have a 'hold invoice' for which the
|
||||
// htlc will be accepted and held until the preimage becomes known.
|
||||
Hash *lntypes.Hash
|
||||
|
||||
// The value of this invoice in satoshis.
|
||||
Value btcutil.Amount
|
||||
|
||||
@@ -87,19 +94,58 @@ type AddInvoiceData struct {
|
||||
}
|
||||
|
||||
// AddInvoice attempts to add a new invoice to the invoice database. Any
|
||||
// duplicated invoices are rejected, therefore all invoices *must* have a unique
|
||||
// payment preimage. AddInvoice returns the payment hash and the invoice
|
||||
// structure as stored in the database.
|
||||
// duplicated invoices are rejected, therefore all invoices *must* have a
|
||||
// unique payment preimage.
|
||||
func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
|
||||
invoice *AddInvoiceData) (*lntypes.Hash, *channeldb.Invoice, error) {
|
||||
|
||||
var paymentPreimage lntypes.Preimage
|
||||
if invoice.Preimage == nil {
|
||||
var (
|
||||
paymentPreimage lntypes.Preimage
|
||||
paymentHash lntypes.Hash
|
||||
)
|
||||
|
||||
switch {
|
||||
|
||||
// Only either preimage or hash can be set.
|
||||
case invoice.Preimage != nil && invoice.Hash != nil:
|
||||
return nil, nil,
|
||||
errors.New("preimage and hash both set")
|
||||
|
||||
// Prevent the unknown preimage magic value from being used for a
|
||||
// regular invoice. This would cause the invoice the be handled as if it
|
||||
// was a hold invoice.
|
||||
case invoice.Preimage != nil &&
|
||||
*invoice.Preimage == channeldb.UnknownPreimage:
|
||||
|
||||
return nil, nil,
|
||||
fmt.Errorf("cannot use all zeroes as a preimage")
|
||||
|
||||
// Prevent the hash of the unknown preimage magic value to be used for a
|
||||
// hold invoice. This would make it impossible to settle the invoice,
|
||||
// because it would still be interpreted as not having a preimage.
|
||||
case invoice.Hash != nil &&
|
||||
*invoice.Hash == channeldb.UnknownPreimage.Hash():
|
||||
|
||||
return nil, nil,
|
||||
fmt.Errorf("cannot use hash of all zeroes preimage")
|
||||
|
||||
// If no hash or preimage is given, generate a random preimage.
|
||||
case invoice.Preimage == nil && invoice.Hash == nil:
|
||||
if _, err := rand.Read(paymentPreimage[:]); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
paymentHash = paymentPreimage.Hash()
|
||||
|
||||
// If just a hash is given, we create a hold invoice by setting the
|
||||
// preimage to unknown.
|
||||
case invoice.Preimage == nil && invoice.Hash != nil:
|
||||
paymentPreimage = channeldb.UnknownPreimage
|
||||
paymentHash = *invoice.Hash
|
||||
|
||||
// A specific preimage was supplied. Use that for the invoice.
|
||||
case invoice.Preimage != nil && invoice.Hash == nil:
|
||||
paymentPreimage = *invoice.Preimage
|
||||
paymentHash = invoice.Preimage.Hash()
|
||||
}
|
||||
|
||||
// The size of the memo, receipt and description hash attached must not
|
||||
@@ -134,10 +180,6 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
|
||||
)
|
||||
}
|
||||
|
||||
// Next, generate the payment hash itself from the preimage. This will
|
||||
// be used by clients to query for the state of a particular invoice.
|
||||
rHash := paymentPreimage.Hash()
|
||||
|
||||
// We also create an encoded payment request which allows the
|
||||
// caller to compactly send the invoice to the payer. We'll create a
|
||||
// list of options to be added to the encoded payment request. For now
|
||||
@@ -332,7 +374,7 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
|
||||
// Create and encode the payment request as a bech32 (zpay32) string.
|
||||
creationDate := time.Now()
|
||||
payReq, err := zpay32.NewInvoice(
|
||||
cfg.ChainParams, rHash, creationDate, options...,
|
||||
cfg.ChainParams, paymentHash, creationDate, options...,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -365,10 +407,10 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
|
||||
)
|
||||
|
||||
// With all sanity checks passed, write the invoice to the database.
|
||||
_, err = cfg.AddInvoice(newInvoice, rHash)
|
||||
_, err = cfg.AddInvoice(newInvoice, paymentHash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return &rHash, newInvoice, nil
|
||||
return &paymentHash, newInvoice, nil
|
||||
}
|
||||
|
@@ -65,11 +65,10 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
|
||||
invoice.Terms.State)
|
||||
}
|
||||
|
||||
return &lnrpc.Invoice{
|
||||
rpcInvoice := &lnrpc.Invoice{
|
||||
Memo: string(invoice.Memo[:]),
|
||||
Receipt: invoice.Receipt[:],
|
||||
RHash: decoded.PaymentHash[:],
|
||||
RPreimage: preimage[:],
|
||||
Value: int64(satAmt),
|
||||
CreationDate: invoice.CreationDate.Unix(),
|
||||
SettleDate: settleDate,
|
||||
@@ -87,7 +86,13 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
|
||||
AmtPaidMsat: int64(invoice.AmtPaid),
|
||||
AmtPaid: int64(invoice.AmtPaid),
|
||||
State: state,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if preimage != channeldb.UnknownPreimage {
|
||||
rpcInvoice.RPreimage = preimage[:]
|
||||
}
|
||||
|
||||
return rpcInvoice, nil
|
||||
}
|
||||
|
||||
// CreateRPCRouteHints takes in the decoded form of an invoice's route hints
|
||||
|
Reference in New Issue
Block a user