invoices/invoiceregistry: explicitly set blank pay addr for keysend

This commit is contained in:
Conner Fromknecht 2020-06-26 02:17:18 -07:00
parent 11e9fd3e92
commit 20dea0d6bc
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7
2 changed files with 57 additions and 17 deletions

@ -676,6 +676,15 @@ func (i *InvoiceRegistry) processKeySend(ctx invoiceUpdateCtx) error {
return errors.New("final expiry too soon") return errors.New("final expiry too soon")
} }
// The invoice database indexes all invoices by payment address, however
// legacy keysend payment do not have one. In order to avoid a new
// payment type on-disk wrt. to indexing, we'll continue to insert a
// blank payment address which is special cased in the insertion logic
// to not be indexed. In the future, once AMP is merged, this should be
// replaced by generating a random payment address on the behalf of the
// sender.
payAddr := channeldb.BlankPayAddr
// Create placeholder invoice. // Create placeholder invoice.
invoice := &channeldb.Invoice{ invoice := &channeldb.Invoice{
CreationDate: i.cfg.Clock.Now(), CreationDate: i.cfg.Clock.Now(),
@ -683,6 +692,7 @@ func (i *InvoiceRegistry) processKeySend(ctx invoiceUpdateCtx) error {
FinalCltvDelta: finalCltvDelta, FinalCltvDelta: finalCltvDelta,
Value: amt, Value: amt,
PaymentPreimage: &preimage, PaymentPreimage: &preimage,
PaymentAddr: payAddr,
Features: features, Features: features,
}, },
} }

@ -725,29 +725,59 @@ func testKeySend(t *testing.T, keySendEnabled bool) {
return return
} }
// Otherwise we expect no error and a settle resolution for the htlc. checkResolution := func(res HtlcResolution, pimg lntypes.Preimage) {
settleResolution, ok := resolution.(*HtlcSettleResolution) // Otherwise we expect no error and a settle res for the htlc.
if !ok { settleResolution, ok := res.(*HtlcSettleResolution)
t.Fatalf("expected settle resolution, got: %T", assert.True(t, ok)
resolution) assert.Equal(t, settleResolution.Preimage, pimg)
} }
if settleResolution.Preimage != preimage { checkSubscription := func() {
t.Fatalf("expected settle with matching preimage") // We expect a new invoice notification to be sent out.
newInvoice := <-allSubscriptions.NewInvoices
assert.Equal(t, newInvoice.State, channeldb.ContractOpen)
// We expect a settled notification to be sent out.
settledInvoice := <-allSubscriptions.SettledInvoices
assert.Equal(t, settledInvoice.State, channeldb.ContractSettled)
} }
// We expect a new invoice notification to be sent out. checkResolution(resolution, preimage)
newInvoice := <-allSubscriptions.NewInvoices checkSubscription()
if newInvoice.State != channeldb.ContractOpen {
t.Fatalf("expected state ContractOpen, but got %v", // Replay the same keysend payment. We expect an identical resolution,
newInvoice.State) // but no event should be generated.
resolution, err = ctx.registry.NotifyExitHopHtlc(
hash, amt, expiry,
testCurrentHeight, getCircuitKey(10), hodlChan, keySendPayload,
)
assert.Nil(t, err)
checkResolution(resolution, preimage)
select {
case <-allSubscriptions.NewInvoices:
t.Fatalf("replayed keysend should not generate event")
case <-time.After(time.Second):
} }
// We expect a settled notification to be sent out. // Finally, test that we can properly fulfill a second keysend payment
settledInvoice := <-allSubscriptions.SettledInvoices // with a unique preiamge.
if settledInvoice.State != channeldb.ContractSettled { preimage2 := lntypes.Preimage{1, 2, 3, 4}
t.Fatalf("expected state ContractOpen, but got %v", hash2 := preimage2.Hash()
settledInvoice.State)
keySendPayload2 := &mockPayload{
customRecords: map[uint64][]byte{
record.KeySendType: preimage2[:],
},
} }
resolution, err = ctx.registry.NotifyExitHopHtlc(
hash2, amt, expiry,
testCurrentHeight, getCircuitKey(20), hodlChan, keySendPayload2,
)
assert.Nil(t, err)
checkResolution(resolution, preimage2)
checkSubscription()
} }
// TestMppPayment tests settling of an invoice with multiple partial payments. // TestMppPayment tests settling of an invoice with multiple partial payments.