multi: break invoice depenency on channeldb
Now that we have the new package `lnd/channeldb/models` we can invert the depenency between `channeldb` and `invoices`. - Move all the invoice related types and errors to the `invoices` package. - Ensure that all the packages dealing with invoices use the types and interfaces defined in the `invoices` package. - Implement the InvoiceDB interface (defined in `lnd/invoices`) in channeldb. - Add new mock for InterfaceDB. - `InvoiceRegistery` tests are now in its own subpacakge (they need to import both invoices & channeldb). This is temporary until we can decouple them.
This commit is contained in:
26 files changed
+2839
-2253
No files matched your search
+42
-43
@@ -5,8 +5,6 @@ import (
|
||||
"errors"
|
||||
|
||||
"github.com/lightningnetwork/lnd/amp"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/channeldb/models"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/record"
|
||||
@@ -16,7 +14,7 @@ import (
|
||||
// update to be carried out.
|
||||
type invoiceUpdateCtx struct {
|
||||
hash lntypes.Hash
|
||||
circuitKey models.CircuitKey
|
||||
circuitKey CircuitKey
|
||||
amtPaid lnwire.MilliSatoshi
|
||||
expiry uint32
|
||||
currentHeight int32
|
||||
@@ -29,16 +27,18 @@ type invoiceUpdateCtx struct {
|
||||
|
||||
// invoiceRef returns an identifier that can be used to lookup or update the
|
||||
// invoice this HTLC is targeting.
|
||||
func (i *invoiceUpdateCtx) invoiceRef() channeldb.InvoiceRef {
|
||||
func (i *invoiceUpdateCtx) invoiceRef() InvoiceRef {
|
||||
switch {
|
||||
case i.amp != nil && i.mpp != nil:
|
||||
payAddr := i.mpp.PaymentAddr()
|
||||
return channeldb.InvoiceRefByAddr(payAddr)
|
||||
return InvoiceRefByAddr(payAddr)
|
||||
|
||||
case i.mpp != nil:
|
||||
payAddr := i.mpp.PaymentAddr()
|
||||
return channeldb.InvoiceRefByHashAndAddr(i.hash, payAddr)
|
||||
return InvoiceRefByHashAndAddr(i.hash, payAddr)
|
||||
|
||||
default:
|
||||
return channeldb.InvoiceRefByHash(i.hash)
|
||||
return InvoiceRefByHash(i.hash)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,20 +95,20 @@ func (i invoiceUpdateCtx) acceptRes(outcome acceptResolutionResult) *htlcAcceptR
|
||||
// updateInvoice is a callback for DB.UpdateInvoice that contains the invoice
|
||||
// settlement logic. It returns a hltc resolution that indicates what the
|
||||
// outcome of the update was.
|
||||
func updateInvoice(ctx *invoiceUpdateCtx, inv *channeldb.Invoice) (
|
||||
*channeldb.InvoiceUpdateDesc, HtlcResolution, error) {
|
||||
func updateInvoice(ctx *invoiceUpdateCtx, inv *Invoice) (
|
||||
*InvoiceUpdateDesc, HtlcResolution, error) {
|
||||
|
||||
// Don't update the invoice when this is a replayed htlc.
|
||||
htlc, ok := inv.Htlcs[ctx.circuitKey]
|
||||
if ok {
|
||||
switch htlc.State {
|
||||
case channeldb.HtlcStateCanceled:
|
||||
case HtlcStateCanceled:
|
||||
return nil, ctx.failRes(ResultReplayToCanceled), nil
|
||||
|
||||
case channeldb.HtlcStateAccepted:
|
||||
case HtlcStateAccepted:
|
||||
return nil, ctx.acceptRes(resultReplayToAccepted), nil
|
||||
|
||||
case channeldb.HtlcStateSettled:
|
||||
case HtlcStateSettled:
|
||||
pre := inv.Terms.PaymentPreimage
|
||||
|
||||
// Terms.PaymentPreimage will be nil for AMP invoices.
|
||||
@@ -139,8 +139,7 @@ func updateInvoice(ctx *invoiceUpdateCtx, inv *channeldb.Invoice) (
|
||||
|
||||
// updateMpp is a callback for DB.UpdateInvoice that contains the invoice
|
||||
// settlement logic for mpp payments.
|
||||
func updateMpp(ctx *invoiceUpdateCtx,
|
||||
inv *channeldb.Invoice) (*channeldb.InvoiceUpdateDesc,
|
||||
func updateMpp(ctx *invoiceUpdateCtx, inv *Invoice) (*InvoiceUpdateDesc,
|
||||
HtlcResolution, error) {
|
||||
|
||||
// Reject HTLCs to AMP invoices if they are missing an AMP payload, and
|
||||
@@ -160,7 +159,7 @@ func updateMpp(ctx *invoiceUpdateCtx,
|
||||
setID := ctx.setID()
|
||||
|
||||
// Start building the accept descriptor.
|
||||
acceptDesc := &channeldb.HtlcAcceptDesc{
|
||||
acceptDesc := &HtlcAcceptDesc{
|
||||
Amt: ctx.amtPaid,
|
||||
Expiry: ctx.expiry,
|
||||
AcceptHeight: ctx.currentHeight,
|
||||
@@ -169,7 +168,7 @@ func updateMpp(ctx *invoiceUpdateCtx,
|
||||
}
|
||||
|
||||
if ctx.amp != nil {
|
||||
acceptDesc.AMP = &channeldb.InvoiceHtlcAMPData{
|
||||
acceptDesc.AMP = &InvoiceHtlcAMPData{
|
||||
Record: *ctx.amp,
|
||||
Hash: ctx.hash,
|
||||
Preimage: nil,
|
||||
@@ -180,7 +179,7 @@ func updateMpp(ctx *invoiceUpdateCtx,
|
||||
// non-mpp payments that are accepted even after the invoice is settled.
|
||||
// Because non-mpp payments don't have a payment address, this is needed
|
||||
// to thwart probing.
|
||||
if inv.State != channeldb.ContractOpen {
|
||||
if inv.State != ContractOpen {
|
||||
return nil, ctx.failRes(ResultInvoiceNotOpen), nil
|
||||
}
|
||||
|
||||
@@ -200,7 +199,7 @@ func updateMpp(ctx *invoiceUpdateCtx,
|
||||
return nil, ctx.failRes(ResultHtlcSetTotalTooLow), nil
|
||||
}
|
||||
|
||||
htlcSet := inv.HTLCSet(setID, channeldb.HtlcStateAccepted)
|
||||
htlcSet := inv.HTLCSet(setID, HtlcStateAccepted)
|
||||
|
||||
// Check whether total amt matches other htlcs in the set.
|
||||
var newSetTotal lnwire.MilliSatoshi
|
||||
@@ -229,16 +228,16 @@ func updateMpp(ctx *invoiceUpdateCtx,
|
||||
return nil, ctx.failRes(ResultExpiryTooSoon), nil
|
||||
}
|
||||
|
||||
if setID != nil && *setID == channeldb.BlankPayAddr {
|
||||
if setID != nil && *setID == BlankPayAddr {
|
||||
return nil, ctx.failRes(ResultAmpError), nil
|
||||
}
|
||||
|
||||
// Record HTLC in the invoice database.
|
||||
newHtlcs := map[models.CircuitKey]*channeldb.HtlcAcceptDesc{
|
||||
newHtlcs := map[CircuitKey]*HtlcAcceptDesc{
|
||||
ctx.circuitKey: acceptDesc,
|
||||
}
|
||||
|
||||
update := channeldb.InvoiceUpdateDesc{
|
||||
update := InvoiceUpdateDesc{
|
||||
AddHtlcs: newHtlcs,
|
||||
}
|
||||
|
||||
@@ -251,23 +250,23 @@ func updateMpp(ctx *invoiceUpdateCtx,
|
||||
// Check to see if we can settle or this is an hold invoice and
|
||||
// we need to wait for the preimage.
|
||||
if inv.HodlInvoice {
|
||||
update.State = &channeldb.InvoiceStateUpdateDesc{
|
||||
NewState: channeldb.ContractAccepted,
|
||||
update.State = &InvoiceStateUpdateDesc{
|
||||
NewState: ContractAccepted,
|
||||
SetID: setID,
|
||||
}
|
||||
return &update, ctx.acceptRes(resultAccepted), nil
|
||||
}
|
||||
|
||||
var (
|
||||
htlcPreimages map[models.CircuitKey]lntypes.Preimage
|
||||
htlcPreimages map[CircuitKey]lntypes.Preimage
|
||||
htlcPreimage lntypes.Preimage
|
||||
)
|
||||
if ctx.amp != nil {
|
||||
var failRes *HtlcFailResolution
|
||||
htlcPreimages, failRes = reconstructAMPPreimages(ctx, htlcSet)
|
||||
if failRes != nil {
|
||||
update.State = &channeldb.InvoiceStateUpdateDesc{
|
||||
NewState: channeldb.ContractCanceled,
|
||||
update.State = &InvoiceStateUpdateDesc{
|
||||
NewState: ContractCanceled,
|
||||
SetID: setID,
|
||||
}
|
||||
return &update, failRes, nil
|
||||
@@ -280,8 +279,8 @@ func updateMpp(ctx *invoiceUpdateCtx,
|
||||
htlcPreimage = *inv.Terms.PaymentPreimage
|
||||
}
|
||||
|
||||
update.State = &channeldb.InvoiceStateUpdateDesc{
|
||||
NewState: channeldb.ContractSettled,
|
||||
update.State = &InvoiceStateUpdateDesc{
|
||||
NewState: ContractSettled,
|
||||
Preimage: inv.Terms.PaymentPreimage,
|
||||
HTLCPreimages: htlcPreimages,
|
||||
SetID: setID,
|
||||
@@ -291,10 +290,10 @@ func updateMpp(ctx *invoiceUpdateCtx,
|
||||
}
|
||||
|
||||
// HTLCSet is a map of CircuitKey to InvoiceHTLC.
|
||||
type HTLCSet = map[models.CircuitKey]*channeldb.InvoiceHTLC
|
||||
type HTLCSet = map[CircuitKey]*InvoiceHTLC
|
||||
|
||||
// HTLCPreimages is a map of CircuitKey to preimage.
|
||||
type HTLCPreimages = map[models.CircuitKey]lntypes.Preimage
|
||||
type HTLCPreimages = map[CircuitKey]lntypes.Preimage
|
||||
|
||||
// reconstructAMPPreimages reconstructs the root seed for an AMP HTLC set and
|
||||
// verifies that all derived child hashes match the payment hashes of the HTLCs
|
||||
@@ -317,7 +316,7 @@ func reconstructAMPPreimages(ctx *invoiceUpdateCtx,
|
||||
|
||||
// Next, construct an index mapping the position in childDescs to a
|
||||
// circuit key for all preexisting HTLCs.
|
||||
indexToCircuitKey := make(map[int]models.CircuitKey)
|
||||
indexToCircuitKey := make(map[int]CircuitKey)
|
||||
|
||||
// Add the child descriptor for each HTLC in the HTLC set, recording
|
||||
// it's position within the slice.
|
||||
@@ -351,7 +350,7 @@ func reconstructAMPPreimages(ctx *invoiceUpdateCtx,
|
||||
// Finally, construct the map of learned preimages indexed by circuit
|
||||
// key, so that they can be persisted along with each HTLC when updating
|
||||
// the invoice.
|
||||
htlcPreimages := make(map[models.CircuitKey]lntypes.Preimage)
|
||||
htlcPreimages := make(map[CircuitKey]lntypes.Preimage)
|
||||
htlcPreimages[ctx.circuitKey] = children[0].Preimage
|
||||
for idx, child := range children[1:] {
|
||||
circuitKey := indexToCircuitKey[idx]
|
||||
@@ -368,11 +367,11 @@ func reconstructAMPPreimages(ctx *invoiceUpdateCtx,
|
||||
// send payments and any invoices we created in the past that are valid and
|
||||
// still had the optional mpp bit set.
|
||||
func updateLegacy(ctx *invoiceUpdateCtx,
|
||||
inv *channeldb.Invoice) (*channeldb.InvoiceUpdateDesc, HtlcResolution, error) {
|
||||
inv *Invoice) (*InvoiceUpdateDesc, HtlcResolution, error) {
|
||||
|
||||
// If the invoice is already canceled, there is no further
|
||||
// checking to do.
|
||||
if inv.State == channeldb.ContractCanceled {
|
||||
if inv.State == ContractCanceled {
|
||||
return nil, ctx.failRes(ResultInvoiceAlreadyCanceled), nil
|
||||
}
|
||||
|
||||
@@ -402,7 +401,7 @@ func updateLegacy(ctx *invoiceUpdateCtx,
|
||||
// Don't allow settling the invoice with an old style
|
||||
// htlc if we are already in the process of gathering an
|
||||
// mpp set.
|
||||
for _, htlc := range inv.HTLCSet(nil, channeldb.HtlcStateAccepted) {
|
||||
for _, htlc := range inv.HTLCSet(nil, HtlcStateAccepted) {
|
||||
if htlc.MppTotalAmt > 0 {
|
||||
return nil, ctx.failRes(ResultMppInProgress), nil
|
||||
}
|
||||
@@ -418,7 +417,7 @@ func updateLegacy(ctx *invoiceUpdateCtx,
|
||||
}
|
||||
|
||||
// Record HTLC in the invoice database.
|
||||
newHtlcs := map[models.CircuitKey]*channeldb.HtlcAcceptDesc{
|
||||
newHtlcs := map[CircuitKey]*HtlcAcceptDesc{
|
||||
ctx.circuitKey: {
|
||||
Amt: ctx.amtPaid,
|
||||
Expiry: ctx.expiry,
|
||||
@@ -427,17 +426,17 @@ func updateLegacy(ctx *invoiceUpdateCtx,
|
||||
},
|
||||
}
|
||||
|
||||
update := channeldb.InvoiceUpdateDesc{
|
||||
update := InvoiceUpdateDesc{
|
||||
AddHtlcs: newHtlcs,
|
||||
}
|
||||
|
||||
// Don't update invoice state if we are accepting a duplicate payment.
|
||||
// We do accept or settle the HTLC.
|
||||
switch inv.State {
|
||||
case channeldb.ContractAccepted:
|
||||
case ContractAccepted:
|
||||
return &update, ctx.acceptRes(resultDuplicateToAccepted), nil
|
||||
|
||||
case channeldb.ContractSettled:
|
||||
case ContractSettled:
|
||||
return &update, ctx.settleRes(
|
||||
*inv.Terms.PaymentPreimage, ResultDuplicateToSettled,
|
||||
), nil
|
||||
@@ -446,15 +445,15 @@ func updateLegacy(ctx *invoiceUpdateCtx,
|
||||
// Check to see if we can settle or this is an hold invoice and we need
|
||||
// to wait for the preimage.
|
||||
if inv.HodlInvoice {
|
||||
update.State = &channeldb.InvoiceStateUpdateDesc{
|
||||
NewState: channeldb.ContractAccepted,
|
||||
update.State = &InvoiceStateUpdateDesc{
|
||||
NewState: ContractAccepted,
|
||||
}
|
||||
|
||||
return &update, ctx.acceptRes(resultAccepted), nil
|
||||
}
|
||||
|
||||
update.State = &channeldb.InvoiceStateUpdateDesc{
|
||||
NewState: channeldb.ContractSettled,
|
||||
update.State = &InvoiceStateUpdateDesc{
|
||||
NewState: ContractSettled,
|
||||
Preimage: inv.Terms.PaymentPreimage,
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user