|
|
|
package liquidity
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/btcsuite/btcutil"
|
|
|
|
"github.com/lightninglabs/loop"
|
|
|
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
|
|
"github.com/lightningnetwork/lnd/routing/route"
|
|
|
|
)
|
|
|
|
|
|
|
|
// FeeLimit is an interface implemented by different strategies for limiting
|
|
|
|
// the fees we pay for autoloops.
|
|
|
|
type FeeLimit interface {
|
|
|
|
// String returns the string representation of fee limits.
|
|
|
|
String() string
|
|
|
|
|
|
|
|
// validate returns an error if the values provided are invalid.
|
|
|
|
validate() error
|
|
|
|
|
|
|
|
// mayLoopOut checks whether we may dispatch a loop out swap based on
|
|
|
|
// the current fee conditions.
|
|
|
|
mayLoopOut(estimate chainfee.SatPerKWeight) error
|
|
|
|
|
|
|
|
// loopOutLimits checks whether the quote provided is within our fee
|
|
|
|
// limits for the swap amount.
|
|
|
|
loopOutLimits(amount btcutil.Amount, quote *loop.LoopOutQuote) error
|
|
|
|
|
|
|
|
// loopOutFees return the maximum prepay and invoice routing fees for
|
|
|
|
// a swap amount and quote.
|
|
|
|
loopOutFees(amount btcutil.Amount, quote *loop.LoopOutQuote) (
|
|
|
|
btcutil.Amount, btcutil.Amount, btcutil.Amount)
|
|
|
|
}
|
|
|
|
|
|
|
|
// swapSuggestion is an interface implemented by suggested swaps for our
|
|
|
|
// different swap types. This interface is used to allow us to handle different
|
|
|
|
// swap types with the same autoloop logic.
|
|
|
|
type swapSuggestion interface {
|
|
|
|
// fees returns the highest possible fee amount we could pay for a swap
|
|
|
|
// in satoshis.
|
|
|
|
fees() btcutil.Amount
|
|
|
|
|
|
|
|
// amount returns the swap amount in satoshis.
|
|
|
|
amount() btcutil.Amount
|
|
|
|
|
|
|
|
// channels returns the set of channels involved in the swap.
|
|
|
|
channels() []lnwire.ShortChannelID
|
|
|
|
|
|
|
|
// peers returns the set of peers involved in the swap, taking a map
|
|
|
|
// of known channel IDs to peers as an argument so that channel peers
|
|
|
|
// can be looked up.
|
|
|
|
peers(knownChans map[uint64]route.Vertex) []route.Vertex
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compile-time assertion that loopOutSwapSuggestion satisfies the
|
|
|
|
// swapSuggestion interface.
|
|
|
|
var _ swapSuggestion = (*loopOutSwapSuggestion)(nil)
|
|
|
|
|
|
|
|
type loopOutSwapSuggestion struct {
|
|
|
|
loop.OutRequest
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *loopOutSwapSuggestion) amount() btcutil.Amount {
|
|
|
|
return l.Amount
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *loopOutSwapSuggestion) fees() btcutil.Amount {
|
|
|
|
return worstCaseOutFees(
|
|
|
|
l.MaxPrepayRoutingFee, l.MaxSwapRoutingFee, l.MaxSwapFee,
|
|
|
|
l.MaxMinerFee, l.MaxPrepayAmount,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *loopOutSwapSuggestion) channels() []lnwire.ShortChannelID {
|
|
|
|
channels := make([]lnwire.ShortChannelID, len(l.OutgoingChanSet))
|
|
|
|
|
|
|
|
for i, id := range l.OutgoingChanSet {
|
|
|
|
channels[i] = lnwire.NewShortChanIDFromInt(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
return channels
|
|
|
|
}
|
|
|
|
|
|
|
|
// peers returns the set of peers that the loop out swap is restricted to.
|
|
|
|
func (l *loopOutSwapSuggestion) peers(
|
|
|
|
knownChans map[uint64]route.Vertex) []route.Vertex {
|
|
|
|
|
|
|
|
peers := make(map[route.Vertex]struct{}, len(knownChans))
|
|
|
|
|
|
|
|
for _, channel := range l.OutgoingChanSet {
|
|
|
|
peer, ok := knownChans[channel]
|
|
|
|
if !ok {
|
|
|
|
log.Warnf("peer for channel: %v unknown", channel)
|
|
|
|
}
|
|
|
|
|
|
|
|
peers[peer] = struct{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
peerList := make([]route.Vertex, 0, len(peers))
|
|
|
|
for peer := range peers {
|
|
|
|
peerList = append(peerList, peer)
|
|
|
|
}
|
|
|
|
|
|
|
|
return peerList
|
|
|
|
}
|