multi: add explicit hodl invoice flag to invoice

Previously it wasn't possible to store a preimage in the invoice
database and signal that a payment should not be settled right away. The
only way to hold a payment was to insert the magic UnknownPreimage value
in the invoice database. This commit introduces a distinct flag to
signal that an invoice is a hold invoice and thereby allows the preimage
to be present in the database already.

Preparation for (key send) hodl invoices for which we already know the
preimage.
This commit is contained in:
Joost Jager committed 2020-06-02 07:34:23 +02:00
1 parent bdc0d875bc
commit d416ed59ea
11 files changed
+153 -93

No files matched your search

+9 -21
View File
@@ -88,6 +88,10 @@ type AddInvoiceData struct {
// Whether this invoice should include routing hints for private
// channels.
Private bool
// HodlInvoice signals that this invoice shouldn't be settled
// immediately upon receiving the payment.
HodlInvoice bool
}
// AddInvoice attempts to add a new invoice to the invoice database. Any
@@ -97,7 +101,7 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
invoice *AddInvoiceData) (*lntypes.Hash, *channeldb.Invoice, error) {
var (
paymentPreimage lntypes.Preimage
paymentPreimage *lntypes.Preimage
paymentHash lntypes.Hash
)
@@ -108,26 +112,9 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
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:
paymentPreimage = &lntypes.Preimage{}
if _, err := rand.Read(paymentPreimage[:]); err != nil {
return nil, nil, err
}
@@ -136,12 +123,12 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
// 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
preimage := *invoice.Preimage
paymentPreimage = &preimage
paymentHash = invoice.Preimage.Hash()
}
@@ -410,6 +397,7 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
PaymentAddr: paymentAddr,
Features: invoiceFeatures,
},
HodlInvoice: invoice.HodlInvoice,
}
log.Tracef("[addinvoice] adding new invoice %v",
+2
View File
@@ -274,6 +274,8 @@ func (s *Server) AddHoldInvoice(ctx context.Context,
FallbackAddr: invoice.FallbackAddr,
CltvExpiry: invoice.CltvExpiry,
Private: invoice.Private,
HodlInvoice: true,
Preimage: nil,
}
_, dbInvoice, err := AddInvoice(ctx, addInvoiceCfg, addInvoiceData)
+2 -2
View File
@@ -22,7 +22,7 @@ func decodePayReq(invoice *channeldb.Invoice,
paymentRequest := string(invoice.PaymentRequest)
if paymentRequest == "" {
preimage := invoice.Terms.PaymentPreimage
if preimage == channeldb.UnknownPreimage {
if preimage == nil {
return nil, errors.New("cannot reconstruct pay req")
}
hash := [32]byte(preimage.Hash())
@@ -149,7 +149,7 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
IsKeysend: len(invoice.PaymentRequest) == 0,
}
if preimage != channeldb.UnknownPreimage {
if preimage != nil {
rpcInvoice.RPreimage = preimage[:]
}