diff --git a/contractcourt/htlc_incoming_contest_resolver.go b/contractcourt/htlc_incoming_contest_resolver.go index b104f8d70..6bda4e398 100644 --- a/contractcourt/htlc_incoming_contest_resolver.go +++ b/contractcourt/htlc_incoming_contest_resolver.go @@ -308,7 +308,7 @@ func (h *htlcIncomingContestResolver) Resolve( resolution, err := h.Registry.NotifyExitHopHtlc( h.htlc.RHash, h.htlc.Amt, h.htlcExpiry, currentHeight, - circuitKey, hodlQueue.ChanIn(), payload, + circuitKey, hodlQueue.ChanIn(), nil, payload, ) if err != nil { return nil, err diff --git a/contractcourt/interfaces.go b/contractcourt/interfaces.go index 0d53b07b6..90ad2b1c8 100644 --- a/contractcourt/interfaces.go +++ b/contractcourt/interfaces.go @@ -30,6 +30,7 @@ type Registry interface { NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi, expiry uint32, currentHeight int32, circuitKey models.CircuitKey, hodlChan chan<- interface{}, + wireCustomRecords lnwire.CustomRecords, payload invoices.Payload) (invoices.HtlcResolution, error) // HodlUnsubscribeAll unsubscribes from all htlc resolutions. diff --git a/contractcourt/mock_registry_test.go b/contractcourt/mock_registry_test.go index 7acac67ec..5c7518562 100644 --- a/contractcourt/mock_registry_test.go +++ b/contractcourt/mock_registry_test.go @@ -26,6 +26,7 @@ type mockRegistry struct { func (r *mockRegistry) NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi, expiry uint32, currentHeight int32, circuitKey models.CircuitKey, hodlChan chan<- interface{}, + wireCustomRecords lnwire.CustomRecords, payload invoices.Payload) (invoices.HtlcResolution, error) { r.notifyChan <- notifyExitHopData{ diff --git a/htlcswitch/interfaces.go b/htlcswitch/interfaces.go index ca653a326..3dd70247d 100644 --- a/htlcswitch/interfaces.go +++ b/htlcswitch/interfaces.go @@ -33,6 +33,7 @@ type InvoiceDatabase interface { NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi, expiry uint32, currentHeight int32, circuitKey models.CircuitKey, hodlChan chan<- interface{}, + wireCustomRecords lnwire.CustomRecords, payload invoices.Payload) (invoices.HtlcResolution, error) // CancelInvoice attempts to cancel the invoice corresponding to the diff --git a/htlcswitch/link.go b/htlcswitch/link.go index 928f35d44..e7766bc81 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -3846,7 +3846,7 @@ func (l *channelLink) processExitHop(add lnwire.UpdateAddHTLC, event, err := l.cfg.Registry.NotifyExitHopHtlc( invoiceHash, add.Amount, add.Expiry, int32(heightNow), - circuitKey, l.hodlQueue.ChanIn(), payload, + circuitKey, l.hodlQueue.ChanIn(), add.CustomRecords, payload, ) if err != nil { return err diff --git a/htlcswitch/mock.go b/htlcswitch/mock.go index f43fc7a94..6de60b38a 100644 --- a/htlcswitch/mock.go +++ b/htlcswitch/mock.go @@ -1049,11 +1049,12 @@ func (i *mockInvoiceRegistry) SettleHodlInvoice( func (i *mockInvoiceRegistry) NotifyExitHopHtlc(rhash lntypes.Hash, amt lnwire.MilliSatoshi, expiry uint32, currentHeight int32, circuitKey models.CircuitKey, hodlChan chan<- interface{}, + wireCustomRecords lnwire.CustomRecords, payload invoices.Payload) (invoices.HtlcResolution, error) { event, err := i.registry.NotifyExitHopHtlc( - rhash, amt, expiry, currentHeight, circuitKey, hodlChan, - payload, + rhash, amt, expiry, currentHeight, circuitKey, + hodlChan, wireCustomRecords, payload, ) if err != nil { return nil, err diff --git a/invoices/invoiceregistry.go b/invoices/invoiceregistry.go index c7f4cdb7b..517e237ca 100644 --- a/invoices/invoiceregistry.go +++ b/invoices/invoiceregistry.go @@ -918,6 +918,7 @@ func (i *InvoiceRegistry) processAMP(ctx invoiceUpdateCtx) error { func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash, amtPaid lnwire.MilliSatoshi, expiry uint32, currentHeight int32, circuitKey CircuitKey, hodlChan chan<- interface{}, + wireCustomRecords lnwire.CustomRecords, payload Payload) (HtlcResolution, error) { // Create the update context containing the relevant details of the @@ -929,6 +930,7 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash, expiry: expiry, currentHeight: currentHeight, finalCltvRejectDelta: i.cfg.FinalCltvRejectDelta, + wireCustomRecords: wireCustomRecords, customRecords: payload.CustomRecords(), mpp: payload.MultiPath(), amp: payload.AMPRecord(), @@ -1051,6 +1053,7 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked( // the interceptor's client an opportunity to manipulate the // settlement process. err = i.cfg.HtlcInterceptor.Intercept(HtlcModifyRequest{ + WireCustomRecords: ctx.wireCustomRecords, ExitHtlcCircuitKey: ctx.circuitKey, ExitHtlcAmt: ctx.amtPaid, ExitHtlcExpiry: ctx.expiry, diff --git a/invoices/invoiceregistry_test.go b/invoices/invoiceregistry_test.go index b7b3d574a..3deb6405c 100644 --- a/invoices/invoiceregistry_test.go +++ b/invoices/invoiceregistry_test.go @@ -245,7 +245,8 @@ func testSettleInvoice(t *testing.T, resolution, err := ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, testInvoice.Terms.Value, uint32(testCurrentHeight)+testInvoiceCltvDelta-1, - testCurrentHeight, getCircuitKey(10), hodlChan, testPayload, + testCurrentHeight, getCircuitKey(10), hodlChan, + nil, testPayload, ) if err != nil { t.Fatal(err) @@ -261,7 +262,7 @@ func testSettleInvoice(t *testing.T, resolution, err = ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, amtPaid, testHtlcExpiry, testCurrentHeight, getCircuitKey(0), hodlChan, - testPayload, + nil, testPayload, ) if err != nil { t.Fatal(err) @@ -302,7 +303,8 @@ func testSettleInvoice(t *testing.T, // behaviour after a restart. resolution, err = ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, amtPaid, testHtlcExpiry, - testCurrentHeight, getCircuitKey(0), hodlChan, testPayload, + testCurrentHeight, getCircuitKey(0), hodlChan, + nil, testPayload, ) require.NoError(t, err, "unexpected NotifyExitHopHtlc error") require.NotNil(t, resolution) @@ -316,7 +318,8 @@ func testSettleInvoice(t *testing.T, // paid invoice that may open up a probe vector. resolution, err = ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, amtPaid+600, testHtlcExpiry, - testCurrentHeight, getCircuitKey(1), hodlChan, testPayload, + testCurrentHeight, getCircuitKey(1), hodlChan, + nil, testPayload, ) require.NoError(t, err, "unexpected NotifyExitHopHtlc error") require.NotNil(t, resolution) @@ -331,7 +334,8 @@ func testSettleInvoice(t *testing.T, // would have failed if it were the first payment. resolution, err = ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, amtPaid-600, testHtlcExpiry, - testCurrentHeight, getCircuitKey(2), hodlChan, testPayload, + testCurrentHeight, getCircuitKey(2), hodlChan, + nil, testPayload, ) require.NoError(t, err, "unexpected NotifyExitHopHtlc error") require.NotNil(t, resolution) @@ -468,7 +472,8 @@ func testCancelInvoiceImpl(t *testing.T, gc bool, hodlChan := make(chan interface{}) resolution, err := ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, testInvoiceAmount, testHtlcExpiry, - testCurrentHeight, getCircuitKey(0), hodlChan, testPayload, + testCurrentHeight, getCircuitKey(0), hodlChan, + nil, testPayload, ) if err != nil { t.Fatal("expected settlement of a canceled invoice to succeed") @@ -577,7 +582,8 @@ func testSettleHoldInvoice(t *testing.T, // should be possible. resolution, err := registry.NotifyExitHopHtlc( testInvoicePaymentHash, amtPaid, testHtlcExpiry, - testCurrentHeight, getCircuitKey(0), hodlChan, testPayload, + testCurrentHeight, getCircuitKey(0), hodlChan, + nil, testPayload, ) if err != nil { t.Fatalf("expected settle to succeed but got %v", err) @@ -589,7 +595,8 @@ func testSettleHoldInvoice(t *testing.T, // Test idempotency. resolution, err = registry.NotifyExitHopHtlc( testInvoicePaymentHash, amtPaid, testHtlcExpiry, - testCurrentHeight, getCircuitKey(0), hodlChan, testPayload, + testCurrentHeight, getCircuitKey(0), hodlChan, + nil, testPayload, ) if err != nil { t.Fatalf("expected settle to succeed but got %v", err) @@ -602,7 +609,8 @@ func testSettleHoldInvoice(t *testing.T, // is a replay. resolution, err = registry.NotifyExitHopHtlc( testInvoicePaymentHash, amtPaid, testHtlcExpiry, - testCurrentHeight+10, getCircuitKey(0), hodlChan, testPayload, + testCurrentHeight+10, getCircuitKey(0), hodlChan, + nil, testPayload, ) if err != nil { t.Fatalf("expected settle to succeed but got %v", err) @@ -615,7 +623,7 @@ func testSettleHoldInvoice(t *testing.T, // requirement. It should be rejected. resolution, err = registry.NotifyExitHopHtlc( testInvoicePaymentHash, amtPaid, 1, testCurrentHeight, - getCircuitKey(1), hodlChan, testPayload, + getCircuitKey(1), hodlChan, nil, testPayload, ) if err != nil { t.Fatalf("expected settle to succeed but got %v", err) @@ -719,7 +727,8 @@ func testCancelHoldInvoice(t *testing.T, // should be possible. resolution, err := registry.NotifyExitHopHtlc( testInvoicePaymentHash, amtPaid, testHtlcExpiry, - testCurrentHeight, getCircuitKey(0), hodlChan, testPayload, + testCurrentHeight, getCircuitKey(0), hodlChan, + nil, testPayload, ) if err != nil { t.Fatalf("expected settle to succeed but got %v", err) @@ -741,7 +750,8 @@ func testCancelHoldInvoice(t *testing.T, // accept height. resolution, err = registry.NotifyExitHopHtlc( testInvoicePaymentHash, amtPaid, testHtlcExpiry, - testCurrentHeight+1, getCircuitKey(0), hodlChan, testPayload, + testCurrentHeight+1, getCircuitKey(0), hodlChan, + nil, testPayload, ) if err != nil { t.Fatalf("expected settle to succeed but got %v", err) @@ -770,7 +780,7 @@ func testUnknownInvoice(t *testing.T, amt := lnwire.MilliSatoshi(100000) resolution, err := ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, amt, testHtlcExpiry, testCurrentHeight, - getCircuitKey(0), hodlChan, testPayload, + getCircuitKey(0), hodlChan, nil, testPayload, ) if err != nil { t.Fatal("unexpected error") @@ -831,7 +841,7 @@ func testKeySendImpl(t *testing.T, keySendEnabled bool, resolution, err := ctx.registry.NotifyExitHopHtlc( hash, amt, expiry, testCurrentHeight, getCircuitKey(10), hodlChan, - invalidKeySendPayload, + nil, invalidKeySendPayload, ) if err != nil { t.Fatal(err) @@ -852,8 +862,8 @@ func testKeySendImpl(t *testing.T, keySendEnabled bool, } resolution, err = ctx.registry.NotifyExitHopHtlc( - hash, amt, expiry, - testCurrentHeight, getCircuitKey(10), hodlChan, keySendPayload, + hash, amt, expiry, testCurrentHeight, getCircuitKey(10), + hodlChan, nil, keySendPayload, ) if err != nil { t.Fatal(err) @@ -881,8 +891,8 @@ func testKeySendImpl(t *testing.T, keySendEnabled bool, // Replay the same keysend payment. We expect an identical resolution, // but no event should be generated. resolution, err = ctx.registry.NotifyExitHopHtlc( - hash, amt, expiry, - testCurrentHeight, getCircuitKey(10), hodlChan, keySendPayload, + hash, amt, expiry, testCurrentHeight, getCircuitKey(10), + hodlChan, nil, keySendPayload, ) require.Nil(t, err) checkSettleResolution(t, resolution, preimage) @@ -905,8 +915,8 @@ func testKeySendImpl(t *testing.T, keySendEnabled bool, } resolution, err = ctx.registry.NotifyExitHopHtlc( - hash2, amt, expiry, - testCurrentHeight, getCircuitKey(20), hodlChan, keySendPayload2, + hash2, amt, expiry, testCurrentHeight, getCircuitKey(20), + hodlChan, nil, keySendPayload2, ) require.Nil(t, err) @@ -964,8 +974,8 @@ func testHoldKeysendImpl(t *testing.T, timeoutKeysend bool, } resolution, err := ctx.registry.NotifyExitHopHtlc( - hash, amt, expiry, - testCurrentHeight, getCircuitKey(10), hodlChan, keysendPayload, + hash, amt, expiry, testCurrentHeight, getCircuitKey(10), + hodlChan, nil, keysendPayload, ) if err != nil { t.Fatal(err) @@ -1047,8 +1057,8 @@ func testMppPayment(t *testing.T, hodlChan1 := make(chan interface{}, 1) resolution, err := ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, testInvoice.Terms.Value/2, - testHtlcExpiry, - testCurrentHeight, getCircuitKey(10), hodlChan1, mppPayload, + testHtlcExpiry, testCurrentHeight, getCircuitKey(10), + hodlChan1, nil, mppPayload, ) if err != nil { t.Fatal(err) @@ -1075,8 +1085,8 @@ func testMppPayment(t *testing.T, hodlChan2 := make(chan interface{}, 1) resolution, err = ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, testInvoice.Terms.Value/2, - testHtlcExpiry, - testCurrentHeight, getCircuitKey(11), hodlChan2, mppPayload, + testHtlcExpiry, testCurrentHeight, getCircuitKey(11), + hodlChan2, nil, mppPayload, ) if err != nil { t.Fatal(err) @@ -1089,8 +1099,8 @@ func testMppPayment(t *testing.T, hodlChan3 := make(chan interface{}, 1) resolution, err = ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, testInvoice.Terms.Value/2, - testHtlcExpiry, - testCurrentHeight, getCircuitKey(12), hodlChan3, mppPayload, + testHtlcExpiry, testCurrentHeight, getCircuitKey(12), + hodlChan3, nil, mppPayload, ) if err != nil { t.Fatal(err) @@ -1149,7 +1159,7 @@ func testMppPaymentWithOverpayment(t *testing.T, resolution, err := ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, testInvoice.Terms.Value/2, testHtlcExpiry, testCurrentHeight, getCircuitKey(11), - hodlChan1, mppPayload, + hodlChan1, nil, mppPayload, ) if err != nil { t.Fatal(err) @@ -1164,7 +1174,7 @@ func testMppPaymentWithOverpayment(t *testing.T, testInvoicePaymentHash, testInvoice.Terms.Value/2+overpayment, testHtlcExpiry, testCurrentHeight, getCircuitKey(12), hodlChan2, - mppPayload, + nil, mppPayload, ) if err != nil { t.Fatal(err) @@ -1449,7 +1459,7 @@ func testHeightExpiryWithRegistryImpl(t *testing.T, numParts int, settle bool, resolution, err := ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, htlcAmt, expiry, testCurrentHeight, getCircuitKey(uint64(i)), hodlChan, - payLoad, + nil, payLoad, ) require.NoError(t, err) require.Nil(t, resolution, "did not expect direct resolution") @@ -1551,8 +1561,8 @@ func testMultipleSetHeightExpiry(t *testing.T, hodlChan1 := make(chan interface{}, 1) resolution, err := ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, testInvoice.Terms.Value/2, - testHtlcExpiry, - testCurrentHeight, getCircuitKey(10), hodlChan1, mppPayload, + testHtlcExpiry, testCurrentHeight, getCircuitKey(10), + hodlChan1, nil, mppPayload, ) require.NoError(t, err) require.Nil(t, resolution, "did not expect direct resolution") @@ -1581,7 +1591,8 @@ func testMultipleSetHeightExpiry(t *testing.T, hodlChan2 := make(chan interface{}, 1) resolution, err = ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, testInvoice.Terms.Value/2, expiry, - testCurrentHeight, getCircuitKey(11), hodlChan2, mppPayload, + testCurrentHeight, getCircuitKey(11), hodlChan2, + nil, mppPayload, ) require.NoError(t, err) require.Nil(t, resolution, "did not expect direct resolution") @@ -1590,7 +1601,8 @@ func testMultipleSetHeightExpiry(t *testing.T, hodlChan3 := make(chan interface{}, 1) resolution, err = ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, testInvoice.Terms.Value/2, expiry, - testCurrentHeight, getCircuitKey(12), hodlChan3, mppPayload, + testCurrentHeight, getCircuitKey(12), hodlChan3, + nil, mppPayload, ) require.NoError(t, err) require.Nil(t, resolution, "did not expect direct resolution") @@ -1695,7 +1707,8 @@ func testSettleInvoicePaymentAddrRequired(t *testing.T, resolution, err := ctx.registry.NotifyExitHopHtlc( testInvoicePaymentHash, invoice.Terms.Value, uint32(testCurrentHeight)+testInvoiceCltvDelta-1, - testCurrentHeight, getCircuitKey(10), hodlChan, testPayload, + testCurrentHeight, getCircuitKey(10), hodlChan, + nil, testPayload, ) require.NoError(t, err) @@ -1784,9 +1797,9 @@ func testSettleInvoicePaymentAddrRequiredOptionalGrace(t *testing.T, // no problem as we should allow these existing invoices to be settled. hodlChan := make(chan interface{}, 1) resolution, err := ctx.registry.NotifyExitHopHtlc( - testInvoicePaymentHash, testInvoiceAmount, - testHtlcExpiry, testCurrentHeight, - getCircuitKey(10), hodlChan, testPayload, + testInvoicePaymentHash, testInvoiceAmount, testHtlcExpiry, + testCurrentHeight, getCircuitKey(10), hodlChan, + nil, testPayload, ) require.NoError(t, err) @@ -1848,8 +1861,8 @@ func testAMPWithoutMPPPayload(t *testing.T, hodlChan := make(chan interface{}, 1) resolution, err := ctx.registry.NotifyExitHopHtlc( - lntypes.Hash{}, shardAmt, expiry, - testCurrentHeight, getCircuitKey(uint64(10)), hodlChan, + lntypes.Hash{}, shardAmt, expiry, testCurrentHeight, + getCircuitKey(uint64(10)), hodlChan, nil, payload, ) require.NoError(t, err) @@ -2017,8 +2030,8 @@ func testSpontaneousAmpPaymentImpl( } resolution, err := ctx.registry.NotifyExitHopHtlc( - child.Hash, shardAmt, expiry, - testCurrentHeight, getCircuitKey(uint64(i)), hodlChan, + child.Hash, shardAmt, expiry, testCurrentHeight, + getCircuitKey(uint64(i)), hodlChan, nil, payload, ) require.NoError(t, err) diff --git a/invoices/invoices.go b/invoices/invoices.go index 24118f1e5..c48629c58 100644 --- a/invoices/invoices.go +++ b/invoices/invoices.go @@ -547,6 +547,11 @@ type InvoiceHTLC struct { // the htlc. CustomRecords record.CustomSet + // WireCustomRecords contains the custom key/value pairs that were only + // included in p2p wire message of the HTLC and not in the onion + // payload. + WireCustomRecords lnwire.CustomRecords + // AMP encapsulates additional data relevant to AMP HTLCs. This includes // the AMP onion record, in addition to the HTLC's payment hash and // preimage since these are unique to each AMP HTLC, and not the invoice @@ -566,6 +571,7 @@ func (h *InvoiceHTLC) Copy() *InvoiceHTLC { result.CustomRecords[k] = v } + result.WireCustomRecords = h.WireCustomRecords.Copy() result.AMP = h.AMP.Copy() return &result diff --git a/invoices/update.go b/invoices/update.go index d14bafee0..3137bbbfa 100644 --- a/invoices/update.go +++ b/invoices/update.go @@ -21,12 +21,20 @@ type invoiceUpdateCtx struct { expiry uint32 currentHeight int32 finalCltvRejectDelta int32 - customRecords record.CustomSet - mpp *record.MPP - amp *record.AMP - metadata []byte - pathID *chainhash.Hash - totalAmtMsat lnwire.MilliSatoshi + + // wireCustomRecords are the custom records that were included with the + // HTLC wire message. + wireCustomRecords lnwire.CustomRecords + + // customRecords is a map of custom records that were included with the + // HTLC onion payload. + customRecords record.CustomSet + + mpp *record.MPP + amp *record.AMP + metadata []byte + pathID *chainhash.Hash + totalAmtMsat lnwire.MilliSatoshi } // invoiceRef returns an identifier that can be used to lookup or update the @@ -95,12 +103,14 @@ func (i invoiceUpdateCtx) settleRes(preimage lntypes.Preimage, // acceptRes is a helper function which creates an accept resolution with // the information contained in the invoiceUpdateCtx and the accept resolution // result provided. -func (i invoiceUpdateCtx) acceptRes(outcome acceptResolutionResult) *htlcAcceptResolution { +func (i invoiceUpdateCtx) acceptRes( + outcome acceptResolutionResult) *htlcAcceptResolution { + return newAcceptResolution(i.circuitKey, outcome) } // updateInvoice is a callback for DB.UpdateInvoice that contains the invoice -// settlement logic. It returns a hltc resolution that indicates what the +// settlement logic. It returns a HTLC resolution that indicates what the // outcome of the update was. func updateInvoice(ctx *invoiceUpdateCtx, inv *Invoice) ( *InvoiceUpdateDesc, HtlcResolution, error) { @@ -119,7 +129,7 @@ func updateInvoice(ctx *invoiceUpdateCtx, inv *Invoice) ( pre := inv.Terms.PaymentPreimage // Terms.PaymentPreimage will be nil for AMP invoices. - // Set it to the HTLC's AMP Preimage instead. + // Set it to the HTLCs AMP Preimage instead. if pre == nil { pre = htlc.AMP.Preimage } @@ -180,13 +190,19 @@ func updateMpp(ctx *invoiceUpdateCtx, inv *Invoice) (*InvoiceUpdateDesc, paymentAddr = ctx.pathID[:] } + // For storage, we don't really care where the custom records came from. + // So we merge them together and store them in the same field. + customRecords := lnwire.CustomRecords( + ctx.customRecords, + ).MergedCopy(ctx.wireCustomRecords) + // Start building the accept descriptor. acceptDesc := &HtlcAcceptDesc{ Amt: ctx.amtPaid, Expiry: ctx.expiry, AcceptHeight: ctx.currentHeight, MppTotalAmt: totalAmt, - CustomRecords: ctx.customRecords, + CustomRecords: record.CustomSet(customRecords), } if ctx.amp != nil { @@ -223,7 +239,7 @@ func updateMpp(ctx *invoiceUpdateCtx, inv *Invoice) (*InvoiceUpdateDesc, htlcSet := inv.HTLCSet(setID, HtlcStateAccepted) - // Check whether total amt matches other htlcs in the set. + // Check whether total amt matches other HTLCs in the set. var newSetTotal lnwire.MilliSatoshi for _, htlc := range htlcSet { if totalAmt != htlc.MppTotalAmt { @@ -265,7 +281,7 @@ func updateMpp(ctx *invoiceUpdateCtx, inv *Invoice) (*InvoiceUpdateDesc, return &update, ctx.acceptRes(resultPartialAccepted), nil } - // Check to see if we can settle or this is an hold invoice and + // Check to see if we can settle or this is a hold invoice, and // we need to wait for the preimage. if inv.HodlInvoice { update.State = &InvoiceStateUpdateDesc{ @@ -434,13 +450,19 @@ func updateLegacy(ctx *invoiceUpdateCtx, return nil, ctx.failRes(ResultExpiryTooSoon), nil } + // For storage, we don't really care where the custom records came from. + // So we merge them together and store them in the same field. + customRecords := lnwire.CustomRecords( + ctx.customRecords, + ).MergedCopy(ctx.wireCustomRecords) + // Record HTLC in the invoice database. newHtlcs := map[CircuitKey]*HtlcAcceptDesc{ ctx.circuitKey: { Amt: ctx.amtPaid, Expiry: ctx.expiry, AcceptHeight: ctx.currentHeight, - CustomRecords: ctx.customRecords, + CustomRecords: record.CustomSet(customRecords), }, } diff --git a/invoices/update_invoice_test.go b/invoices/update_invoice_test.go index 42d370971..6069fbecd 100644 --- a/invoices/update_invoice_test.go +++ b/invoices/update_invoice_test.go @@ -5,6 +5,7 @@ import ( "time" "github.com/lightningnetwork/lnd/lntypes" + "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/record" "github.com/stretchr/testify/require" ) @@ -37,98 +38,147 @@ func TestUpdateHTLC(t *testing.T) { { name: "MPP accept", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), - AMP: nil, + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), + AMP: nil, }, invState: ContractAccepted, setID: nil, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), - AMP: nil, + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), + AMP: nil, + }, + expErr: nil, + }, + { + name: "MPP accept, copy custom records", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: record.CustomSet{ + 0x01: []byte{0x02}, + 0xffff: []byte{0x04, 0x05, 0x06}, + }, + WireCustomRecords: lnwire.CustomRecords{ + 0x010101: []byte{0x02, 0x03}, + 0xffffff: []byte{0x44, 0x55, 0x66}, + }, + AMP: nil, + }, + invState: ContractAccepted, + setID: nil, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: record.CustomSet{ + 0x01: []byte{0x02}, + 0xffff: []byte{0x04, 0x05, 0x06}, + }, + WireCustomRecords: lnwire.CustomRecords{ + 0x010101: []byte{0x02, 0x03}, + 0xffffff: []byte{0x44, 0x55, 0x66}, + }, + AMP: nil, }, expErr: nil, }, { name: "MPP settle", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), - AMP: nil, + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), + AMP: nil, }, invState: ContractSettled, setID: nil, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testNow, - Expiry: 40, - State: HtlcStateSettled, - CustomRecords: make(record.CustomSet), - AMP: nil, + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), + AMP: nil, }, expErr: nil, }, { name: "MPP cancel", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), - AMP: nil, + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), + AMP: nil, }, invState: ContractCanceled, setID: nil, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testNow, - Expiry: 40, - State: HtlcStateCanceled, - CustomRecords: make(record.CustomSet), - AMP: nil, + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), + AMP: nil, }, expErr: nil, }, { name: "AMP accept missing preimage", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -138,14 +188,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractAccepted, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -157,14 +208,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "AMP accept invalid preimage", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -174,14 +226,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractAccepted, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -193,14 +246,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "AMP accept valid preimage", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -210,14 +264,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractAccepted, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -229,14 +284,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "AMP accept valid preimage different htlc set", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -246,14 +302,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractAccepted, setID: &diffSetID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -265,14 +322,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "AMP settle missing preimage", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -282,14 +340,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractSettled, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -301,14 +360,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "AMP settle invalid preimage", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -318,14 +378,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractSettled, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -337,14 +398,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "AMP settle valid preimage", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -354,14 +416,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractSettled, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testNow, - Expiry: 40, - State: HtlcStateSettled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -377,14 +440,15 @@ func TestUpdateHTLC(t *testing.T) { // remain in the accepted state. name: "AMP settle valid preimage different htlc set", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -394,14 +458,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractSettled, setID: &diffSetID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -413,14 +478,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "accept invoice htlc already settled", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateSettled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -430,14 +496,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractAccepted, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateSettled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -449,14 +516,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "cancel invoice htlc already settled", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateSettled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -466,14 +534,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractCanceled, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateSettled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -485,14 +554,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "settle invoice htlc already settled", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateSettled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -502,14 +572,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractSettled, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateSettled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -521,14 +592,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "cancel invoice", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: time.Time{}, - Expiry: 40, - State: HtlcStateAccepted, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -538,14 +610,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractCanceled, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testNow, - Expiry: 40, - State: HtlcStateCanceled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -557,14 +630,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "accept invoice htlc already canceled", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateCanceled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -574,14 +648,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractAccepted, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateCanceled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -593,14 +668,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "cancel invoice htlc already canceled", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateCanceled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -610,14 +686,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractCanceled, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateCanceled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -629,14 +706,15 @@ func TestUpdateHTLC(t *testing.T) { { name: "settle invoice htlc already canceled", input: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateCanceled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash, @@ -646,14 +724,15 @@ func TestUpdateHTLC(t *testing.T) { invState: ContractSettled, setID: &setID, output: InvoiceHTLC{ - Amt: 5000, - MppTotalAmt: 5000, - AcceptHeight: 100, - AcceptTime: testNow, - ResolveTime: testAlreadyNow, - Expiry: 40, - State: HtlcStateCanceled, - CustomRecords: make(record.CustomSet), + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + WireCustomRecords: make(lnwire.CustomRecords), AMP: &InvoiceHtlcAMPData{ Record: *ampRecord, Hash: hash,