abf780bf03
In this commit, a htlcNotifier interface is added to allow for easy unit testing. Instances of the HtlcNotifier are added to the server, switch and link.
209 lines
8.8 KiB
Go
209 lines
8.8 KiB
Go
package htlcswitch
|
|
|
|
import (
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/lightningnetwork/lnd/channeldb"
|
|
"github.com/lightningnetwork/lnd/invoices"
|
|
"github.com/lightningnetwork/lnd/lnpeer"
|
|
"github.com/lightningnetwork/lnd/lntypes"
|
|
"github.com/lightningnetwork/lnd/lnwallet"
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
)
|
|
|
|
// InvoiceDatabase is an interface which represents the persistent subsystem
|
|
// which may search, lookup and settle invoices.
|
|
type InvoiceDatabase interface {
|
|
// LookupInvoice attempts to look up an invoice according to its 32
|
|
// byte payment hash.
|
|
LookupInvoice(lntypes.Hash) (channeldb.Invoice, error)
|
|
|
|
// NotifyExitHopHtlc attempts to mark an invoice as settled. If the
|
|
// invoice is a debug invoice, then this method is a noop as debug
|
|
// invoices are never fully settled. The return value describes how the
|
|
// htlc should be resolved. If the htlc cannot be resolved immediately,
|
|
// the resolution is sent on the passed in hodlChan later. The eob
|
|
// field passes the entire onion hop payload into the invoice registry
|
|
// for decoding purposes.
|
|
NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi,
|
|
expiry uint32, currentHeight int32,
|
|
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
|
|
payload invoices.Payload) (invoices.HtlcResolution, error)
|
|
|
|
// CancelInvoice attempts to cancel the invoice corresponding to the
|
|
// passed payment hash.
|
|
CancelInvoice(payHash lntypes.Hash) error
|
|
|
|
// SettleHodlInvoice settles a hold invoice.
|
|
SettleHodlInvoice(preimage lntypes.Preimage) error
|
|
|
|
// HodlUnsubscribeAll unsubscribes from all htlc resolutions.
|
|
HodlUnsubscribeAll(subscriber chan<- interface{})
|
|
}
|
|
|
|
// ChannelLink is an interface which represents the subsystem for managing the
|
|
// incoming htlc requests, applying the changes to the channel, and also
|
|
// propagating/forwarding it to htlc switch.
|
|
//
|
|
// abstraction level
|
|
// ^
|
|
// |
|
|
// | - - - - - - - - - - - - Lightning - - - - - - - - - - - - -
|
|
// |
|
|
// | (Switch) (Switch) (Switch)
|
|
// | Alice <-- channel link --> Bob <-- channel link --> Carol
|
|
// |
|
|
// | - - - - - - - - - - - - - TCP - - - - - - - - - - - - - - -
|
|
// |
|
|
// | (Peer) (Peer) (Peer)
|
|
// | Alice <----- tcp conn --> Bob <---- tcp conn -----> Carol
|
|
// |
|
|
//
|
|
type ChannelLink interface {
|
|
// TODO(roasbeef): modify interface to embed mail boxes?
|
|
|
|
// HandleSwitchPacket handles the switch packets. This packets might be
|
|
// forwarded to us from another channel link in case the htlc update
|
|
// came from another peer or if the update was created by user
|
|
// initially.
|
|
//
|
|
// NOTE: This function MUST be non-blocking (or block as little as
|
|
// possible).
|
|
HandleSwitchPacket(*htlcPacket) error
|
|
|
|
// HandleChannelUpdate handles the htlc requests as settle/add/fail
|
|
// which sent to us from remote peer we have a channel with.
|
|
//
|
|
// NOTE: This function MUST be non-blocking (or block as little as
|
|
// possible).
|
|
HandleChannelUpdate(lnwire.Message)
|
|
|
|
// ChannelPoint returns the channel outpoint for the channel link.
|
|
ChannelPoint() *wire.OutPoint
|
|
|
|
// ChanID returns the channel ID for the channel link. The channel ID
|
|
// is a more compact representation of a channel's full outpoint.
|
|
ChanID() lnwire.ChannelID
|
|
|
|
// ShortChanID returns the short channel ID for the channel link. The
|
|
// short channel ID encodes the exact location in the main chain that
|
|
// the original funding output can be found.
|
|
ShortChanID() lnwire.ShortChannelID
|
|
|
|
// UpdateShortChanID updates the short channel ID for a link. This may
|
|
// be required in the event that a link is created before the short
|
|
// chan ID for it is known, or a re-org occurs, and the funding
|
|
// transaction changes location within the chain.
|
|
UpdateShortChanID() (lnwire.ShortChannelID, error)
|
|
|
|
// UpdateForwardingPolicy updates the forwarding policy for the target
|
|
// ChannelLink. Once updated, the link will use the new forwarding
|
|
// policy to govern if it an incoming HTLC should be forwarded or not.
|
|
UpdateForwardingPolicy(ForwardingPolicy)
|
|
|
|
// CheckHtlcForward should return a nil error if the passed HTLC details
|
|
// satisfy the current forwarding policy fo the target link. Otherwise,
|
|
// a LinkError with a valid protocol failure message should be returned
|
|
// in order to signal to the source of the HTLC, the policy consistency
|
|
// issue.
|
|
CheckHtlcForward(payHash [32]byte, incomingAmt lnwire.MilliSatoshi,
|
|
amtToForward lnwire.MilliSatoshi,
|
|
incomingTimeout, outgoingTimeout uint32,
|
|
heightNow uint32) *LinkError
|
|
|
|
// CheckHtlcTransit should return a nil error if the passed HTLC details
|
|
// satisfy the current channel policy. Otherwise, a LinkError with a
|
|
// valid protocol failure message should be returned in order to signal
|
|
// the violation. This call is intended to be used for locally initiated
|
|
// payments for which there is no corresponding incoming htlc.
|
|
CheckHtlcTransit(payHash [32]byte, amt lnwire.MilliSatoshi,
|
|
timeout uint32, heightNow uint32) *LinkError
|
|
|
|
// Bandwidth returns the amount of milli-satoshis which current link
|
|
// might pass through channel link. The value returned from this method
|
|
// represents the up to date available flow through the channel. This
|
|
// takes into account any forwarded but un-cleared HTLC's, and any
|
|
// HTLC's which have been set to the over flow queue.
|
|
Bandwidth() lnwire.MilliSatoshi
|
|
|
|
// Stats return the statistics of channel link. Number of updates,
|
|
// total sent/received milli-satoshis.
|
|
Stats() (uint64, lnwire.MilliSatoshi, lnwire.MilliSatoshi)
|
|
|
|
// Peer returns the representation of remote peer with which we have
|
|
// the channel link opened.
|
|
Peer() lnpeer.Peer
|
|
|
|
// EligibleToForward returns a bool indicating if the channel is able
|
|
// to actively accept requests to forward HTLC's. A channel may be
|
|
// active, but not able to forward HTLC's if it hasn't yet finalized
|
|
// the pre-channel operation protocol with the remote peer. The switch
|
|
// will use this function in forwarding decisions accordingly.
|
|
EligibleToForward() bool
|
|
|
|
// AttachMailBox delivers an active MailBox to the link. The MailBox may
|
|
// have buffered messages.
|
|
AttachMailBox(MailBox)
|
|
|
|
// Start/Stop are used to initiate the start/stop of the channel link
|
|
// functioning.
|
|
Start() error
|
|
Stop()
|
|
}
|
|
|
|
// ForwardingLog is an interface that represents a time series database which
|
|
// keep track of all successfully completed payment circuits. Every few
|
|
// seconds, the switch will collate and flush out all the successful payment
|
|
// circuits during the last interval.
|
|
type ForwardingLog interface {
|
|
// AddForwardingEvents is a method that should write out the set of
|
|
// forwarding events in a batch to persistent storage. Outside
|
|
// sub-systems can then query the contents of the log for analysis,
|
|
// visualizations, etc.
|
|
AddForwardingEvents([]channeldb.ForwardingEvent) error
|
|
}
|
|
|
|
// TowerClient is the primary interface used by the daemon to backup pre-signed
|
|
// justice transactions to watchtowers.
|
|
type TowerClient interface {
|
|
// RegisterChannel persistently initializes any channel-dependent
|
|
// parameters within the client. This should be called during link
|
|
// startup to ensure that the client is able to support the link during
|
|
// operation.
|
|
RegisterChannel(lnwire.ChannelID) error
|
|
|
|
// BackupState initiates a request to back up a particular revoked
|
|
// state. If the method returns nil, the backup is guaranteed to be
|
|
// successful unless the tower is unavailable and client is force quit,
|
|
// or the justice transaction would create dust outputs when trying to
|
|
// abide by the negotiated policy. If the channel we're trying to back
|
|
// up doesn't have a tweak for the remote party's output, then
|
|
// isTweakless should be true.
|
|
BackupState(*lnwire.ChannelID, *lnwallet.BreachRetribution, bool) error
|
|
}
|
|
|
|
// htlcNotifier is an interface which represents the input side of the
|
|
// HtlcNotifier which htlc events are piped through. This interface is intended
|
|
// to allow for mocking of the htlcNotifier in tests, so is unexported because
|
|
// it is not needed outside of the htlcSwitch package.
|
|
type htlcNotifier interface {
|
|
// NotifyForwardingEvent notifies the HtlcNotifier than a htlc has been
|
|
// forwarded.
|
|
NotifyForwardingEvent(key HtlcKey, info HtlcInfo,
|
|
eventType HtlcEventType)
|
|
|
|
// NotifyIncomingLinkFailEvent notifies that a htlc has failed on our
|
|
// incoming link. It takes an isReceive bool to differentiate between
|
|
// our node's receives and forwards.
|
|
NotifyLinkFailEvent(key HtlcKey, info HtlcInfo,
|
|
eventType HtlcEventType, linkErr *LinkError, incoming bool)
|
|
|
|
// NotifyForwardingFailEvent notifies the HtlcNotifier that a htlc we
|
|
// forwarded has failed down the line.
|
|
NotifyForwardingFailEvent(key HtlcKey, eventType HtlcEventType)
|
|
|
|
// NotifySettleEvent notifies the HtlcNotifier that a htlc that we
|
|
// committed to as part of a forward or a receive to our node has been
|
|
// settled.
|
|
NotifySettleEvent(key HtlcKey, eventType HtlcEventType)
|
|
}
|