channeldb: explicitly store the FinalCltvDelta within the ContractTerm struct

In this commit, we move to explicitly storing a bit more information
within the invoice. Currently this information is already stored in the
payment request, but by storing it at this level, callers that may not
be in the state to fully decode a payment request can obtain this data.

We avoid a database migration by appending this data to the end of an
invoice. When decoding, we'll try to read out this extra information,
and simply return what we have if it isn't found.
This commit is contained in:
Olaoluwa Osuntokun 2018-06-26 16:54:50 -07:00
parent 81e647a520
commit 8dcfeeaef5
2 changed files with 24 additions and 3 deletions

@ -3,6 +3,7 @@ package channeldb
import (
"crypto/rand"
"crypto/sha256"
prand "math/rand"
"reflect"
"testing"
"time"
@ -24,6 +25,7 @@ func randInvoice(value lnwire.MilliSatoshi) (*Invoice, error) {
Terms: ContractTerm{
PaymentPreimage: pre,
Value: value,
FinalCltvDelta: uint16(prand.Int31()),
},
}
i.Memo = []byte("memo")
@ -66,6 +68,7 @@ func TestInvoiceWorkflow(t *testing.T) {
fakeInvoice.PaymentRequest = []byte("")
copy(fakeInvoice.Terms.PaymentPreimage[:], rev[:])
fakeInvoice.Terms.Value = lnwire.NewMSatFromSatoshis(10000)
fakeInvoice.Terms.FinalCltvDelta = uint16(prand.Int31())
// Add the invoice to the database, this should succeed as there aren't
// any existing invoices within the database with the same payment

@ -68,6 +68,13 @@ type ContractTerm struct {
// Settled indicates if this particular contract term has been fully
// settled by the payer.
Settled bool
// FinalCltvDelta is the lower bound of a delta from the current height
// that the HTLC that wishes to settle this invoice MUST carry. This
// allows the receiver to specify the time window that should be
// available for them to sweep the HTLC on-chain if that becomes
// necessary.
FinalCltvDelta uint16
}
// Invoice is a payment invoice generated by a payee in order to request
@ -79,8 +86,7 @@ type ContractTerm struct {
// invoices are never deleted from the database, instead a bit is toggled
// denoting the invoice has been fully settled. Within the database, all
// invoices must have a unique payment hash which is generated by taking the
// sha256 of the payment
// preimage.
// sha256 of the payment preimage.
type Invoice struct {
// Memo is an optional memo to be stored along side an invoice. The
// memo may contain further details pertaining to the invoice itself,
@ -361,7 +367,7 @@ func serializeInvoice(w io.Writer, i *Invoice) error {
return err
}
return nil
return binary.Write(w, byteOrder, i.Terms.FinalCltvDelta)
}
func fetchInvoice(invoiceNum []byte, invoices *bolt.Bucket) (*Invoice, error) {
@ -423,6 +429,18 @@ func deserializeInvoice(r io.Reader) (*Invoice, error) {
return nil, err
}
// Before we return with the current invoice, we'll check to see if
// there's still enough space in the buffer to read out the final ctlv
// delta. We'll get an EOF error if there isn't any thing else
// lingering in the buffer.
err = binary.Read(r, byteOrder, &invoice.Terms.FinalCltvDelta)
if err != nil && err != io.EOF {
// If we got a non-eof error, then we know there's an actually
// issue. Otherwise, it may have been the case that this
// summary didn't have the set of optional fields.
return nil, err
}
return invoice, nil
}