channeldb: split cancel and add htlc updates

Previously the cancel and add actions were combined in a single map.
Nil values implictly signaled cancel actions. This wasn't very obvious.
Furthermore this split prepares for processing the adds and cancels
separately, which is more efficient if there are already two maps.
This commit is contained in:
Joost Jager
2019-11-27 14:19:15 +01:00
parent c45891ecf7
commit a4a3c41924
4 changed files with 31 additions and 28 deletions

View File

@@ -686,7 +686,7 @@ func getUpdateInvoice(amt lnwire.MilliSatoshi) InvoiceUpdateCallback {
update := &InvoiceUpdateDesc{ update := &InvoiceUpdateDesc{
Preimage: invoice.Terms.PaymentPreimage, Preimage: invoice.Terms.PaymentPreimage,
State: ContractSettled, State: ContractSettled,
Htlcs: map[CircuitKey]*HtlcAcceptDesc{ AddHtlcs: map[CircuitKey]*HtlcAcceptDesc{
{}: { {}: {
Amt: amt, Amt: amt,
}, },

View File

@@ -316,10 +316,12 @@ type InvoiceUpdateDesc struct {
// State is the new state that this invoice should progress to. // State is the new state that this invoice should progress to.
State ContractState State ContractState
// Htlcs describes the changes that need to be made to the invoice htlcs // CancelHtlcs describes the htlcs that need to be canceled.
// in the database. Htlc map entries with their value set should be CancelHtlcs map[CircuitKey]struct{}
// added. If the map value is nil, the htlc should be canceled.
Htlcs map[CircuitKey]*HtlcAcceptDesc // AddHtlcs describes the newly accepted htlcs that need to be added to
// the invoice.
AddHtlcs map[CircuitKey]*HtlcAcceptDesc
// Preimage must be set to the preimage when state is settled. // Preimage must be set to the preimage when state is settled.
Preimage lntypes.Preimage Preimage lntypes.Preimage
@@ -1251,12 +1253,9 @@ func (d *DB) updateInvoice(hash lntypes.Hash, invoices, settleIndex *bbolt.Bucke
now := d.Now() now := d.Now()
// Update htlc set. // Process cancel actions from update descriptor.
for key, htlcUpdate := range update.Htlcs { for key := range update.CancelHtlcs {
htlc, ok := invoice.Htlcs[key] htlc, ok := invoice.Htlcs[key]
// No update means the htlc needs to be canceled.
if htlcUpdate == nil {
if !ok { if !ok {
return nil, fmt.Errorf("unknown htlc %v", key) return nil, fmt.Errorf("unknown htlc %v", key)
} }
@@ -1268,10 +1267,12 @@ func (d *DB) updateInvoice(hash lntypes.Hash, invoices, settleIndex *bbolt.Bucke
htlc.State = HtlcStateCanceled htlc.State = HtlcStateCanceled
htlc.ResolveTime = now htlc.ResolveTime = now
invoice.AmtPaid -= htlc.Amt invoice.AmtPaid -= htlc.Amt
continue
} }
// Process add actions from update descriptor.
for key, htlcUpdate := range update.AddHtlcs {
htlc, ok := invoice.Htlcs[key]
// Add new htlc paying to the invoice. // Add new htlc paying to the invoice.
if ok { if ok {
return nil, fmt.Errorf("htlc %v already exists", key) return nil, fmt.Errorf("htlc %v already exists", key)

View File

@@ -598,7 +598,7 @@ func (i *InvoiceRegistry) CancelInvoice(payHash lntypes.Hash) error {
// Mark individual held htlcs as canceled. // Mark individual held htlcs as canceled.
canceledHtlcs := make( canceledHtlcs := make(
map[channeldb.CircuitKey]*channeldb.HtlcAcceptDesc, map[channeldb.CircuitKey]struct{},
) )
for key, htlc := range invoice.Htlcs { for key, htlc := range invoice.Htlcs {
switch htlc.State { switch htlc.State {
@@ -615,12 +615,12 @@ func (i *InvoiceRegistry) CancelInvoice(payHash lntypes.Hash) error {
continue continue
} }
canceledHtlcs[key] = nil canceledHtlcs[key] = struct{}{}
} }
// Move invoice to the canceled state. // Move invoice to the canceled state.
return &channeldb.InvoiceUpdateDesc{ return &channeldb.InvoiceUpdateDesc{
Htlcs: canceledHtlcs, CancelHtlcs: canceledHtlcs,
State: channeldb.ContractCanceled, State: channeldb.ContractCanceled,
}, nil }, nil
} }

View File

@@ -130,7 +130,9 @@ func updateInvoice(ctx *invoiceUpdateCtx, inv *channeldb.Invoice) (
}, },
} }
update := channeldb.InvoiceUpdateDesc{Htlcs: newHtlcs} update := channeldb.InvoiceUpdateDesc{
AddHtlcs: newHtlcs,
}
// Don't update invoice state if we are accepting a duplicate payment. // Don't update invoice state if we are accepting a duplicate payment.
// We do accept or settle the HTLC. // We do accept or settle the HTLC.