witness_beacon: do not look up invoice preimages
This commit isolates preimages of forwarded htlcs from invoice preimages. The reason to do this is to prevent the incoming contest resolver from settling exit hop htlcs for which the invoice isn't marked as settled.
This commit is contained in:
parent
99e42ddde6
commit
1a80a1e540
@ -620,7 +620,10 @@ func (c *ChannelArbitrator) stateStep(triggerHeight uint32,
|
||||
// chain, we'll check to see if we need to make any on-chain
|
||||
// claims on behalf of the channel contract that we're
|
||||
// arbitrating for.
|
||||
chainActions := c.checkChainActions(triggerHeight, trigger)
|
||||
chainActions, err := c.checkChainActions(triggerHeight, trigger)
|
||||
if err != nil {
|
||||
return StateError, closeTx, err
|
||||
}
|
||||
|
||||
// If there are no actions to be made, then we'll remain in the
|
||||
// default state. If this isn't a self initiated event (we're
|
||||
@ -1082,7 +1085,7 @@ func (c *ChannelArbitrator) shouldGoOnChain(htlcExpiry, broadcastDelta,
|
||||
// been sufficiently confirmed, the HTLC's should be canceled backwards. For
|
||||
// redeemed HTLC's, we should send the pre-image back to the incoming link.
|
||||
func (c *ChannelArbitrator) checkChainActions(height uint32,
|
||||
trigger transitionTrigger) ChainActionMap {
|
||||
trigger transitionTrigger) (ChainActionMap, error) {
|
||||
|
||||
// TODO(roasbeef): would need to lock channel? channel totem?
|
||||
// * race condition if adding and we broadcast, etc
|
||||
@ -1122,7 +1125,12 @@ func (c *ChannelArbitrator) checkChainActions(height uint32,
|
||||
// know the pre-image and it's close to timing out. We need to
|
||||
// ensure that we claim the funds that our rightfully ours
|
||||
// on-chain.
|
||||
if _, ok := c.cfg.PreimageDB.LookupPreimage(htlc.RHash); !ok {
|
||||
preimageAvailable, err := c.isPreimageAvailable(htlc.RHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !preimageAvailable {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -1151,7 +1159,7 @@ func (c *ChannelArbitrator) checkChainActions(height uint32,
|
||||
if !haveChainActions && trigger == chainTrigger {
|
||||
log.Tracef("ChannelArbitrator(%v): no actions to take at "+
|
||||
"height=%v", c.cfg.ChanPoint, height)
|
||||
return actionMap
|
||||
return actionMap, nil
|
||||
}
|
||||
|
||||
// Now that we know we'll need to go on-chain, we'll examine all of our
|
||||
@ -1223,7 +1231,42 @@ func (c *ChannelArbitrator) checkChainActions(height uint32,
|
||||
)
|
||||
}
|
||||
|
||||
return actionMap
|
||||
return actionMap, nil
|
||||
}
|
||||
|
||||
// isPreimageAvailable returns whether the hash preimage is available in either
|
||||
// the preimage cache or the invoice database.
|
||||
func (c *ChannelArbitrator) isPreimageAvailable(hash lntypes.Hash) (bool,
|
||||
error) {
|
||||
|
||||
// Start by checking the preimage cache for preimages of
|
||||
// forwarded HTLCs.
|
||||
_, preimageAvailable := c.cfg.PreimageDB.LookupPreimage(
|
||||
hash,
|
||||
)
|
||||
if preimageAvailable {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Then check if we have an invoice that can be settled by this HTLC.
|
||||
//
|
||||
// TODO(joostjager): Check that there are still more blocks remaining
|
||||
// than the invoice cltv delta. We don't want to go to chain only to
|
||||
// have the incoming contest resolver decide that we don't want to
|
||||
// settle this invoice.
|
||||
invoice, _, err := c.cfg.Registry.LookupInvoice(hash)
|
||||
switch err {
|
||||
case nil:
|
||||
case channeldb.ErrInvoiceNotFound, channeldb.ErrNoInvoicesCreated:
|
||||
return false, nil
|
||||
default:
|
||||
return false, err
|
||||
}
|
||||
|
||||
preimageAvailable = invoice.Terms.PaymentPreimage !=
|
||||
channeldb.UnknownPreimage
|
||||
|
||||
return preimageAvailable, nil
|
||||
}
|
||||
|
||||
// prepContractResolutions is called either int he case that we decide we need
|
||||
|
@ -374,7 +374,6 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
|
||||
}
|
||||
|
||||
s.witnessBeacon = &preimageBeacon{
|
||||
invoices: s.invoices,
|
||||
wCache: chanDB.NewWitnessCache(),
|
||||
subscribers: make(map[uint64]*preimageSubscriber),
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/contractcourt"
|
||||
"github.com/lightningnetwork/lnd/invoices"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
)
|
||||
|
||||
@ -23,8 +22,6 @@ type preimageSubscriber struct {
|
||||
type preimageBeacon struct {
|
||||
sync.RWMutex
|
||||
|
||||
invoices *invoices.InvoiceRegistry
|
||||
|
||||
wCache *channeldb.WitnessCache
|
||||
|
||||
clientCounter uint64
|
||||
@ -71,25 +68,6 @@ func (p *preimageBeacon) LookupPreimage(
|
||||
p.RLock()
|
||||
defer p.RUnlock()
|
||||
|
||||
// First, we'll check the invoice registry to see if we already know of
|
||||
// the preimage as it's on that we created ourselves.
|
||||
invoice, _, err := p.invoices.LookupInvoice(payHash)
|
||||
switch {
|
||||
case err == channeldb.ErrInvoiceNotFound:
|
||||
// If we get this error, then it simply means that this invoice
|
||||
// wasn't found, so we don't treat it as a critical error.
|
||||
case err != nil:
|
||||
return lntypes.Preimage{}, false
|
||||
}
|
||||
|
||||
// If we've found the invoice, then we can return the preimage
|
||||
// directly.
|
||||
if err != channeldb.ErrInvoiceNotFound &&
|
||||
invoice.Terms.PaymentPreimage != channeldb.UnknownPreimage {
|
||||
|
||||
return invoice.Terms.PaymentPreimage, true
|
||||
}
|
||||
|
||||
// Otherwise, we'll perform a final check using the witness cache.
|
||||
preimage, err := p.wCache.LookupSha256Witness(payHash)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user