mutli: rename HodlEvent to HtlcResolution

This commit renames HodlEvent to HtlcResolution
to better reflect the fact that the struct is
only used for htlc settles and cancels, and that
it is not specifically used for hodl invoices.
This commit is contained in:
carla 2019-12-20 12:25:07 +02:00
parent db85c51b77
commit 2c1eb17192
No known key found for this signature in database
GPG Key ID: 4CA7FE54A6213C91
9 changed files with 73 additions and 70 deletions

@ -167,9 +167,9 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
preimageSubscription := h.PreimageDB.SubscribeUpdates() preimageSubscription := h.PreimageDB.SubscribeUpdates()
defer preimageSubscription.CancelSubscription() defer preimageSubscription.CancelSubscription()
// Define closure to process hodl events either direct or triggered by // Define closure to process htlc resolutions either direct or triggered by
// later notifcation. // later notification.
processHodlEvent := func(e invoices.HodlEvent) (ContractResolver, processHodlEvent := func(e invoices.HtlcResolution) (ContractResolver,
error) { error) {
if e.Preimage == nil { if e.Preimage == nil {
@ -252,9 +252,9 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
return &h.htlcSuccessResolver, nil return &h.htlcSuccessResolver, nil
case hodlItem := <-hodlChan: case hodlItem := <-hodlChan:
hodlEvent := hodlItem.(invoices.HodlEvent) htlcResolution := hodlItem.(invoices.HtlcResolution)
return processHodlEvent(hodlEvent) return processHodlEvent(htlcResolution)
case newBlock, ok := <-blockEpochs.Epochs: case newBlock, ok := <-blockEpochs.Epochs:
if !ok { if !ok {

@ -96,7 +96,7 @@ func TestHtlcIncomingResolverExitSettle(t *testing.T) {
defer timeout(t)() defer timeout(t)()
ctx := newIncomingResolverTestContext(t) ctx := newIncomingResolverTestContext(t)
ctx.registry.notifyEvent = &invoices.HodlEvent{ ctx.registry.notifyEvent = &invoices.HtlcResolution{
CircuitKey: testResCircuitKey, CircuitKey: testResCircuitKey,
Preimage: &testResPreimage, Preimage: &testResPreimage,
} }
@ -126,7 +126,7 @@ func TestHtlcIncomingResolverExitCancel(t *testing.T) {
defer timeout(t)() defer timeout(t)()
ctx := newIncomingResolverTestContext(t) ctx := newIncomingResolverTestContext(t)
ctx.registry.notifyEvent = &invoices.HodlEvent{ ctx.registry.notifyEvent = &invoices.HtlcResolution{
CircuitKey: testResCircuitKey, CircuitKey: testResCircuitKey,
} }
ctx.resolve() ctx.resolve()
@ -143,7 +143,7 @@ func TestHtlcIncomingResolverExitSettleHodl(t *testing.T) {
ctx.resolve() ctx.resolve()
notifyData := <-ctx.registry.notifyChan notifyData := <-ctx.registry.notifyChan
notifyData.hodlChan <- invoices.HodlEvent{ notifyData.hodlChan <- invoices.HtlcResolution{
CircuitKey: testResCircuitKey, CircuitKey: testResCircuitKey,
Preimage: &testResPreimage, Preimage: &testResPreimage,
} }
@ -172,7 +172,7 @@ func TestHtlcIncomingResolverExitCancelHodl(t *testing.T) {
ctx := newIncomingResolverTestContext(t) ctx := newIncomingResolverTestContext(t)
ctx.resolve() ctx.resolve()
notifyData := <-ctx.registry.notifyChan notifyData := <-ctx.registry.notifyChan
notifyData.hodlChan <- invoices.HodlEvent{ notifyData.hodlChan <- invoices.HtlcResolution{
CircuitKey: testResCircuitKey, CircuitKey: testResCircuitKey,
} }
ctx.waitForResult(false) ctx.waitForResult(false)

@ -27,9 +27,9 @@ type Registry interface {
NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi, NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi,
expiry uint32, currentHeight int32, expiry uint32, currentHeight int32,
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{}, circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
payload invoices.Payload) (*invoices.HodlEvent, error) payload invoices.Payload) (*invoices.HtlcResolution, error)
// HodlUnsubscribeAll unsubscribes from all hodl events. // HodlUnsubscribeAll unsubscribes from all htlc resolutions.
HodlUnsubscribeAll(subscriber chan<- interface{}) HodlUnsubscribeAll(subscriber chan<- interface{})
} }

@ -18,13 +18,13 @@ type notifyExitHopData struct {
type mockRegistry struct { type mockRegistry struct {
notifyChan chan notifyExitHopData notifyChan chan notifyExitHopData
notifyErr error notifyErr error
notifyEvent *invoices.HodlEvent notifyEvent *invoices.HtlcResolution
} }
func (r *mockRegistry) NotifyExitHopHtlc(payHash lntypes.Hash, func (r *mockRegistry) NotifyExitHopHtlc(payHash lntypes.Hash,
paidAmount lnwire.MilliSatoshi, expiry uint32, currentHeight int32, paidAmount lnwire.MilliSatoshi, expiry uint32, currentHeight int32,
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{}, circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
payload invoices.Payload) (*invoices.HodlEvent, error) { payload invoices.Payload) (*invoices.HtlcResolution, error) {
r.notifyChan <- notifyExitHopData{ r.notifyChan <- notifyExitHopData{
hodlChan: hodlChan, hodlChan: hodlChan,

@ -27,7 +27,7 @@ type InvoiceDatabase interface {
NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi, NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi,
expiry uint32, currentHeight int32, expiry uint32, currentHeight int32,
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{}, circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
payload invoices.Payload) (*invoices.HodlEvent, error) payload invoices.Payload) (*invoices.HtlcResolution, error)
// CancelInvoice attempts to cancel the invoice corresponding to the // CancelInvoice attempts to cancel the invoice corresponding to the
// passed payment hash. // passed payment hash.
@ -36,7 +36,7 @@ type InvoiceDatabase interface {
// SettleHodlInvoice settles a hold invoice. // SettleHodlInvoice settles a hold invoice.
SettleHodlInvoice(preimage lntypes.Preimage) error SettleHodlInvoice(preimage lntypes.Preimage) error
// HodlUnsubscribeAll unsubscribes from all hodl events. // HodlUnsubscribeAll unsubscribes from all htlc resolutions.
HodlUnsubscribeAll(subscriber chan<- interface{}) HodlUnsubscribeAll(subscriber chan<- interface{})
} }

@ -489,8 +489,8 @@ func (l *channelLink) Stop() {
l.log.Info("stopping") l.log.Info("stopping")
// As the link is stopping, we are no longer interested in hodl events // As the link is stopping, we are no longer interested in htlc
// coming from the invoice registry. // resolutions coming from the invoice registry.
l.cfg.Registry.HodlUnsubscribeAll(l.hodlQueue.ChanIn()) l.cfg.Registry.HodlUnsubscribeAll(l.hodlQueue.ChanIn())
if l.cfg.ChainEvents.Cancel != nil { if l.cfg.ChainEvents.Cancel != nil {
@ -1126,11 +1126,11 @@ out:
case msg := <-l.upstream: case msg := <-l.upstream:
l.handleUpstreamMsg(msg) l.handleUpstreamMsg(msg)
// A hodl event is received. This means that we now have a // A htlc resolution is received. This means that we now have a
// resolution for a previously accepted htlc. // resolution for a previously accepted htlc.
case hodlItem := <-l.hodlQueue.ChanOut(): case hodlItem := <-l.hodlQueue.ChanOut():
hodlEvent := hodlItem.(invoices.HodlEvent) htlcResolution := hodlItem.(invoices.HtlcResolution)
err := l.processHodlQueue(hodlEvent) err := l.processHodlQueue(htlcResolution)
if err != nil { if err != nil {
l.fail(LinkFailureError{code: ErrInternalError}, l.fail(LinkFailureError{code: ErrInternalError},
fmt.Sprintf("process hodl queue: %v", fmt.Sprintf("process hodl queue: %v",
@ -1145,24 +1145,26 @@ out:
} }
} }
// processHodlQueue processes a received hodl event and continues reading from // processHodlQueue processes a received htlc resolution and continues reading
// the hodl queue until no more events remain. When this function returns // from the hodl queue until no more resolutions remain. When this function
// without an error, the commit tx should be updated. // returns without an error, the commit tx should be updated.
func (l *channelLink) processHodlQueue(firstHodlEvent invoices.HodlEvent) error { func (l *channelLink) processHodlQueue(
firstResolution invoices.HtlcResolution) error {
// Try to read all waiting resolution messages, so that they can all be // Try to read all waiting resolution messages, so that they can all be
// processed in a single commitment tx update. // processed in a single commitment tx update.
hodlEvent := firstHodlEvent htlcResolution := firstResolution
loop: loop:
for { for {
// Lookup all hodl htlcs that can be failed or settled with this event. // Lookup all hodl htlcs that can be failed or settled with this event.
// The hodl htlc must be present in the map. // The hodl htlc must be present in the map.
circuitKey := hodlEvent.CircuitKey circuitKey := htlcResolution.CircuitKey
hodlHtlc, ok := l.hodlMap[circuitKey] hodlHtlc, ok := l.hodlMap[circuitKey]
if !ok { if !ok {
return fmt.Errorf("hodl htlc not found: %v", circuitKey) return fmt.Errorf("hodl htlc not found: %v", circuitKey)
} }
if err := l.processHodlEvent(hodlEvent, hodlHtlc); err != nil { if err := l.processHodlEvent(htlcResolution, hodlHtlc); err != nil {
return err return err
} }
@ -1171,7 +1173,7 @@ loop:
select { select {
case item := <-l.hodlQueue.ChanOut(): case item := <-l.hodlQueue.ChanOut():
hodlEvent = item.(invoices.HodlEvent) htlcResolution = item.(invoices.HtlcResolution)
default: default:
break loop break loop
} }
@ -1185,29 +1187,29 @@ loop:
return nil return nil
} }
// processHodlEvent applies a received hodl event to the provided htlc. When // processHodlEvent applies a received htlc resolution to the provided htlc.
// this function returns without an error, the commit tx should be updated. // When this function returns without an error, the commit tx should be updated.
func (l *channelLink) processHodlEvent(hodlEvent invoices.HodlEvent, func (l *channelLink) processHodlEvent(resolution invoices.HtlcResolution,
htlc hodlHtlc) error { htlc hodlHtlc) error {
circuitKey := hodlEvent.CircuitKey circuitKey := resolution.CircuitKey
// Determine required action for the resolution. // Determine required action for the resolution.
if hodlEvent.Preimage != nil { if resolution.Preimage != nil {
l.log.Debugf("received hodl settle event for %v", circuitKey) l.log.Debugf("received settle resolution for %v", circuitKey)
return l.settleHTLC( return l.settleHTLC(
*hodlEvent.Preimage, htlc.pd.HtlcIndex, *resolution.Preimage, htlc.pd.HtlcIndex,
htlc.pd.SourceRef, htlc.pd.SourceRef,
) )
} }
l.log.Debugf("received hodl cancel event for %v", circuitKey) l.log.Debugf("received cancel resolution for %v", circuitKey)
// In case of a cancel, always return // In case of a cancel, always return
// incorrect_or_unknown_payment_details in order to avoid leaking info. // incorrect_or_unknown_payment_details in order to avoid leaking info.
failure := lnwire.NewFailIncorrectDetails( failure := lnwire.NewFailIncorrectDetails(
htlc.pd.Amount, uint32(hodlEvent.AcceptHeight), htlc.pd.Amount, uint32(resolution.AcceptHeight),
) )
l.sendHTLCError( l.sendHTLCError(

@ -819,7 +819,7 @@ func (i *mockInvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error
func (i *mockInvoiceRegistry) NotifyExitHopHtlc(rhash lntypes.Hash, func (i *mockInvoiceRegistry) NotifyExitHopHtlc(rhash lntypes.Hash,
amt lnwire.MilliSatoshi, expiry uint32, currentHeight int32, amt lnwire.MilliSatoshi, expiry uint32, currentHeight int32,
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{}, circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
payload invoices.Payload) (*invoices.HodlEvent, error) { payload invoices.Payload) (*invoices.HtlcResolution, error) {
event, err := i.registry.NotifyExitHopHtlc( event, err := i.registry.NotifyExitHopHtlc(
rhash, amt, expiry, currentHeight, circuitKey, hodlChan, rhash, amt, expiry, currentHeight, circuitKey, hodlChan,

@ -35,10 +35,10 @@ const (
DefaultHtlcHoldDuration = 120 * time.Second DefaultHtlcHoldDuration = 120 * time.Second
) )
// HodlEvent describes how an htlc should be resolved. If HodlEvent.Preimage is // HtlcResolution describes how an htlc should be resolved. If the preimage
// set, the event indicates a settle event. If Preimage is nil, it is a cancel // field is set, the event indicates a settle event. If Preimage is nil, it is
// event. // a cancel event.
type HodlEvent struct { type HtlcResolution struct {
// Preimage is the htlc preimage. Its value is nil in case of a cancel. // Preimage is the htlc preimage. Its value is nil in case of a cancel.
Preimage *lntypes.Preimage Preimage *lntypes.Preimage
@ -652,7 +652,7 @@ func (i *InvoiceRegistry) cancelSingleHtlc(hash lntypes.Hash,
return fmt.Errorf("htlc %v not found", key) return fmt.Errorf("htlc %v not found", key)
} }
if htlc.State == channeldb.HtlcStateCanceled { if htlc.State == channeldb.HtlcStateCanceled {
i.notifyHodlSubscribers(HodlEvent{ i.notifyHodlSubscribers(HtlcResolution{
CircuitKey: key, CircuitKey: key,
AcceptHeight: int32(htlc.AcceptHeight), AcceptHeight: int32(htlc.AcceptHeight),
Preimage: nil, Preimage: nil,
@ -679,7 +679,7 @@ func (i *InvoiceRegistry) cancelSingleHtlc(hash lntypes.Hash,
func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash, func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
amtPaid lnwire.MilliSatoshi, expiry uint32, currentHeight int32, amtPaid lnwire.MilliSatoshi, expiry uint32, currentHeight int32,
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{}, circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
payload Payload) (*HodlEvent, error) { payload Payload) (*HtlcResolution, error) {
i.Lock() i.Lock()
defer i.Unlock() defer i.Unlock()
@ -745,7 +745,7 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
// If it isn't recorded, cancel htlc. // If it isn't recorded, cancel htlc.
if !ok { if !ok {
return &HodlEvent{ return &HtlcResolution{
CircuitKey: circuitKey, CircuitKey: circuitKey,
AcceptHeight: currentHeight, AcceptHeight: currentHeight,
}, nil }, nil
@ -759,7 +759,7 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
switch invoiceHtlc.State { switch invoiceHtlc.State {
case channeldb.HtlcStateCanceled: case channeldb.HtlcStateCanceled:
return &HodlEvent{ return &HtlcResolution{
CircuitKey: circuitKey, CircuitKey: circuitKey,
AcceptHeight: acceptHeight, AcceptHeight: acceptHeight,
}, nil }, nil
@ -773,14 +773,14 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
continue continue
} }
i.notifyHodlSubscribers(HodlEvent{ i.notifyHodlSubscribers(HtlcResolution{
CircuitKey: key, CircuitKey: key,
Preimage: &invoice.Terms.PaymentPreimage, Preimage: &invoice.Terms.PaymentPreimage,
AcceptHeight: int32(htlc.AcceptHeight), AcceptHeight: int32(htlc.AcceptHeight),
}) })
} }
return &HodlEvent{ return &HtlcResolution{
CircuitKey: circuitKey, CircuitKey: circuitKey,
Preimage: &invoice.Terms.PaymentPreimage, Preimage: &invoice.Terms.PaymentPreimage,
AcceptHeight: acceptHeight, AcceptHeight: acceptHeight,
@ -854,7 +854,7 @@ func (i *InvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error {
continue continue
} }
i.notifyHodlSubscribers(HodlEvent{ i.notifyHodlSubscribers(HtlcResolution{
CircuitKey: key, CircuitKey: key,
Preimage: &preimage, Preimage: &preimage,
AcceptHeight: int32(htlc.AcceptHeight), AcceptHeight: int32(htlc.AcceptHeight),
@ -932,7 +932,7 @@ func (i *InvoiceRegistry) cancelInvoiceImpl(payHash lntypes.Hash,
continue continue
} }
i.notifyHodlSubscribers(HodlEvent{ i.notifyHodlSubscribers(HtlcResolution{
CircuitKey: key, CircuitKey: key,
AcceptHeight: int32(htlc.AcceptHeight), AcceptHeight: int32(htlc.AcceptHeight),
}) })
@ -1201,9 +1201,10 @@ func (i *InvoiceRegistry) SubscribeSingleInvoice(
return client, nil return client, nil
} }
// notifyHodlSubscribers sends out the hodl event to all current subscribers. // notifyHodlSubscribers sends out the htlc resolution to all current
func (i *InvoiceRegistry) notifyHodlSubscribers(hodlEvent HodlEvent) { // subscribers.
subscribers, ok := i.hodlSubscriptions[hodlEvent.CircuitKey] func (i *InvoiceRegistry) notifyHodlSubscribers(htlcResolution HtlcResolution) {
subscribers, ok := i.hodlSubscriptions[htlcResolution.CircuitKey]
if !ok { if !ok {
return return
} }
@ -1213,18 +1214,18 @@ func (i *InvoiceRegistry) notifyHodlSubscribers(hodlEvent HodlEvent) {
// single resolution for each hash. // single resolution for each hash.
for subscriber := range subscribers { for subscriber := range subscribers {
select { select {
case subscriber <- hodlEvent: case subscriber <- htlcResolution:
case <-i.quit: case <-i.quit:
return return
} }
delete( delete(
i.hodlReverseSubscriptions[subscriber], i.hodlReverseSubscriptions[subscriber],
hodlEvent.CircuitKey, htlcResolution.CircuitKey,
) )
} }
delete(i.hodlSubscriptions, hodlEvent.CircuitKey) delete(i.hodlSubscriptions, htlcResolution.CircuitKey)
} }
// hodlSubscribe adds a new invoice subscription. // hodlSubscribe adds a new invoice subscription.

@ -281,7 +281,7 @@ func TestCancelInvoice(t *testing.T) {
} }
if event.Preimage != nil { if event.Preimage != nil {
t.Fatal("expected cancel hodl event") t.Fatal("expected cancel htlc resolution")
} }
if event.AcceptHeight != testCurrentHeight { if event.AcceptHeight != testCurrentHeight {
t.Fatalf("expected acceptHeight %v, but got %v", t.Fatalf("expected acceptHeight %v, but got %v",
@ -421,11 +421,11 @@ func TestSettleHoldInvoice(t *testing.T) {
t.Fatal("expected set preimage to succeed") t.Fatal("expected set preimage to succeed")
} }
hodlEvent := (<-hodlChan).(HodlEvent) htlcResolution := (<-hodlChan).(HtlcResolution)
if *hodlEvent.Preimage != testInvoicePreimage { if *htlcResolution.Preimage != testInvoicePreimage {
t.Fatal("unexpected preimage in hodl event") t.Fatal("unexpected preimage in hodl resolution")
} }
if hodlEvent.AcceptHeight != testCurrentHeight { if htlcResolution.AcceptHeight != testCurrentHeight {
t.Fatalf("expected acceptHeight %v, but got %v", t.Fatalf("expected acceptHeight %v, but got %v",
testCurrentHeight, event.AcceptHeight) testCurrentHeight, event.AcceptHeight)
} }
@ -513,9 +513,9 @@ func TestCancelHoldInvoice(t *testing.T) {
t.Fatal("cancel invoice failed") t.Fatal("cancel invoice failed")
} }
hodlEvent := (<-hodlChan).(HodlEvent) htlcResolution := (<-hodlChan).(HtlcResolution)
if hodlEvent.Preimage != nil { if htlcResolution.Preimage != nil {
t.Fatal("expected cancel hodl event") t.Fatal("expected cancel htlc resolution")
} }
// Offering the same htlc again at a higher height should still result // Offering the same htlc again at a higher height should still result
@ -538,10 +538,10 @@ func TestCancelHoldInvoice(t *testing.T) {
} }
// TestUnknownInvoice tests that invoice registry returns an error when the // TestUnknownInvoice tests that invoice registry returns an error when the
// invoice is unknown. This is to guard against returning a cancel hodl event // invoice is unknown. This is to guard against returning a cancel htlc
// for forwarded htlcs. In the link, NotifyExitHopHtlc is only called if we are // resolution for forwarded htlcs. In the link, NotifyExitHopHtlc is only called
// the exit hop, but in htlcIncomingContestResolver it is called with forwarded // if we are the exit hop, but in htlcIncomingContestResolver it is called with
// htlc hashes as well. // forwarded htlc hashes as well.
func TestUnknownInvoice(t *testing.T) { func TestUnknownInvoice(t *testing.T) {
ctx := newTestContext(t) ctx := newTestContext(t)
defer ctx.cleanup() defer ctx.cleanup()
@ -593,8 +593,8 @@ func TestSettleMpp(t *testing.T) {
// Simulate mpp timeout releasing htlc 1. // Simulate mpp timeout releasing htlc 1.
ctx.clock.SetTime(testTime.Add(30 * time.Second)) ctx.clock.SetTime(testTime.Add(30 * time.Second))
hodlEvent := (<-hodlChan1).(HodlEvent) htlcResolution := (<-hodlChan1).(HtlcResolution)
if hodlEvent.Preimage != nil { if htlcResolution.Preimage != nil {
t.Fatal("expected cancel event") t.Fatal("expected cancel event")
} }