cnct+htlcswitch+invoices: move invoice parameter check out of link
This commit is the final step in making the link unaware of invoices. It now purely offers the htlc to the invoice registry and follows instructions from the invoice registry about how and when to respond to the htlc. The change also fixes a bug where upon restart, hodl htlcs were subjected to the invoice minimum cltv delta requirement again. If the block height has increased in the mean while, the htlc would be canceled back. Furthermore the invoice registry interaction is aligned between link and contract resolvers.
This commit is contained in:
16 files changed
+533
-265
No files matched your search
@@ -99,7 +99,10 @@ func TestInvoiceWorkflow(t *testing.T) {
|
||||
// now have the settled bit toggle to true and a non-default
|
||||
// SettledDate
|
||||
payAmt := fakeInvoice.Terms.Value * 2
|
||||
if _, err := db.AcceptOrSettleInvoice(paymentHash, payAmt); err != nil {
|
||||
_, err = db.AcceptOrSettleInvoice(
|
||||
paymentHash, payAmt, checkHtlcParameters,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to settle invoice: %v", err)
|
||||
}
|
||||
dbInvoice2, err := db.LookupInvoice(paymentHash)
|
||||
@@ -261,7 +264,9 @@ func TestInvoiceAddTimeSeries(t *testing.T) {
|
||||
|
||||
paymentHash := invoice.Terms.PaymentPreimage.Hash()
|
||||
|
||||
_, err := db.AcceptOrSettleInvoice(paymentHash, 0)
|
||||
_, err := db.AcceptOrSettleInvoice(
|
||||
paymentHash, 0, checkHtlcParameters,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to settle invoice: %v", err)
|
||||
}
|
||||
@@ -342,7 +347,9 @@ func TestDuplicateSettleInvoice(t *testing.T) {
|
||||
}
|
||||
|
||||
// With the invoice in the DB, we'll now attempt to settle the invoice.
|
||||
dbInvoice, err := db.AcceptOrSettleInvoice(payHash, amt)
|
||||
dbInvoice, err := db.AcceptOrSettleInvoice(
|
||||
payHash, amt, checkHtlcParameters,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to settle invoice: %v", err)
|
||||
}
|
||||
@@ -362,7 +369,9 @@ func TestDuplicateSettleInvoice(t *testing.T) {
|
||||
|
||||
// If we try to settle the invoice again, then we should get the very
|
||||
// same invoice back, but with an error this time.
|
||||
dbInvoice, err = db.AcceptOrSettleInvoice(payHash, amt)
|
||||
dbInvoice, err = db.AcceptOrSettleInvoice(
|
||||
payHash, amt, checkHtlcParameters,
|
||||
)
|
||||
if err != ErrInvoiceAlreadySettled {
|
||||
t.Fatalf("expected ErrInvoiceAlreadySettled")
|
||||
}
|
||||
@@ -407,7 +416,10 @@ func TestQueryInvoices(t *testing.T) {
|
||||
|
||||
// We'll only settle half of all invoices created.
|
||||
if i%2 == 0 {
|
||||
if _, err := db.AcceptOrSettleInvoice(paymentHash, i); err != nil {
|
||||
_, err := db.AcceptOrSettleInvoice(
|
||||
paymentHash, i, checkHtlcParameters,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to settle invoice: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -648,3 +660,7 @@ func TestQueryInvoices(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkHtlcParameters(invoice *Invoice) error {
|
||||
return nil
|
||||
}
|
||||
+17
-3
@@ -631,8 +631,12 @@ func (d *DB) QueryInvoices(q InvoiceQuery) (InvoiceSlice, error) {
|
||||
//
|
||||
// When the preimage for the invoice is unknown (hold invoice), the invoice is
|
||||
// marked as accepted.
|
||||
//
|
||||
// TODO: Store invoice cltv as separate field in database so that it doesn't
|
||||
// need to be decoded from the payment request.
|
||||
func (d *DB) AcceptOrSettleInvoice(paymentHash [32]byte,
|
||||
amtPaid lnwire.MilliSatoshi) (*Invoice, error) {
|
||||
amtPaid lnwire.MilliSatoshi,
|
||||
checkHtlcParameters func(invoice *Invoice) error) (*Invoice, error) {
|
||||
|
||||
var settledInvoice *Invoice
|
||||
err := d.Update(func(tx *bbolt.Tx) error {
|
||||
@@ -662,6 +666,7 @@ func (d *DB) AcceptOrSettleInvoice(paymentHash [32]byte,
|
||||
|
||||
settledInvoice, err = acceptOrSettleInvoice(
|
||||
invoices, settleIndex, invoiceNum, amtPaid,
|
||||
checkHtlcParameters,
|
||||
)
|
||||
|
||||
return err
|
||||
@@ -988,8 +993,10 @@ func deserializeInvoice(r io.Reader) (Invoice, error) {
|
||||
return invoice, nil
|
||||
}
|
||||
|
||||
func acceptOrSettleInvoice(invoices, settleIndex *bbolt.Bucket, invoiceNum []byte,
|
||||
amtPaid lnwire.MilliSatoshi) (*Invoice, error) {
|
||||
func acceptOrSettleInvoice(invoices, settleIndex *bbolt.Bucket,
|
||||
invoiceNum []byte, amtPaid lnwire.MilliSatoshi,
|
||||
checkHtlcParameters func(invoice *Invoice) error) (
|
||||
*Invoice, error) {
|
||||
|
||||
invoice, err := fetchInvoice(invoiceNum, invoices)
|
||||
if err != nil {
|
||||
@@ -1007,6 +1014,13 @@ func acceptOrSettleInvoice(invoices, settleIndex *bbolt.Bucket, invoiceNum []byt
|
||||
return &invoice, ErrInvoiceAlreadyCanceled
|
||||
}
|
||||
|
||||
// If the invoice is still open, check the htlc parameters.
|
||||
if err := checkHtlcParameters(&invoice); err != nil {
|
||||
return &invoice, err
|
||||
}
|
||||
|
||||
// Check to see if we can settle or this is an hold invoice and we need
|
||||
// to wait for the preimage.
|
||||
holdInvoice := invoice.Terms.PaymentPreimage == UnknownPreimage
|
||||
if holdInvoice {
|
||||
invoice.Terms.State = ContractAccepted
|
||||
|
||||
Reference in new issue
Block a user