mirror of
https://github.com/rkfg/regolancer
synced 2024-11-15 00:15:27 +00:00
exclude-from and exclude-to
This commit is contained in:
parent
64b23b3017
commit
916e6b8627
10
README.md
10
README.md
@ -81,19 +81,21 @@ in `~/go/bin/linux_arm`.
|
|||||||
-b, --probe-steps= if the payment fails at the last hop try to probe lower amount using this many steps
|
-b, --probe-steps= if the payment fails at the last hop try to probe lower amount using this many steps
|
||||||
--allow-rapid-rebalance if a rebalance succeeds the route will be used for further rebalances until criteria for channels is not satifsied
|
--allow-rapid-rebalance if a rebalance succeeds the route will be used for further rebalances until criteria for channels is not satifsied
|
||||||
--min-amount= if probing is enabled this will be the minimum amount to try
|
--min-amount= if probing is enabled this will be the minimum amount to try
|
||||||
-i, --exclude-channel-in= don't use this channel as incoming (can be specified multiple times)
|
-i, --exclude-channel-in= (DEPRECATED) don't use this channel as incoming (can be specified multiple times)
|
||||||
-o, --exclude-channel-out= don't use this channel as outgoing (can be specified multiple times)
|
-o, --exclude-channel-out= (DEPRECATED) don't use this channel as outgoing (can be specified multiple times)
|
||||||
|
--exclude-from= don't use this node or channel as source (can be specified multiple times)
|
||||||
|
--exclude-to= don't use this node or channel as target (can be specified multiple times)
|
||||||
-e, --exclude-channel= (DEPRECATED) don't use this channel at all (can be specified multiple times)
|
-e, --exclude-channel= (DEPRECATED) don't use this channel at all (can be specified multiple times)
|
||||||
-d, --exclude-node= (DEPRECATED) don't use this node for routing (can be specified multiple times)
|
-d, --exclude-node= (DEPRECATED) don't use this node for routing (can be specified multiple times)
|
||||||
--exclude= don't use this node or your channel for routing (can be specified multiple times)
|
--exclude= don't use this node or your channel for routing (can be specified multiple times)
|
||||||
--to= try only this channel or node as target (should satisfy other constraints too; can be specified multiple times)
|
--to= try only this channel or node as target (should satisfy other constraints too; can be specified multiple times)
|
||||||
--from= try only this channel or node as source (should satisfy other constraints too; can be specified multiple times)
|
--from= try only this channel or node as source (should satisfy other constraints too; can be specified multiple times)
|
||||||
--fail-tolerance= if a channel failed before during this rebalance but chosen again by lnd, and the forward amount differs by less than this ppm, exclude the channel
|
--fail-tolerance= a payment that differs from the prior attempt by this ppm will be cancelled
|
||||||
--allow-unbalance-from let the source channel go below 50% local liquidity, use if you want to drain a channel; you should also set --pfrom to >50
|
--allow-unbalance-from let the source channel go below 50% local liquidity, use if you want to drain a channel; you should also set --pfrom to >50
|
||||||
--allow-unbalance-to let the target channel go above 50% local liquidity, use if you want to refill a channel; you should also set --pto to >50
|
--allow-unbalance-to let the target channel go above 50% local liquidity, use if you want to refill a channel; you should also set --pto to >50
|
||||||
-s, --stat= save successful rebalance information to the specified CSV file
|
-s, --stat= save successful rebalance information to the specified CSV file
|
||||||
--node-cache-filename= save and load other nodes information to this file, improves cold start performance
|
--node-cache-filename= save and load other nodes information to this file, improves cold start performance
|
||||||
--node-cache-lifetime= nodes with last update older than this time (in minutes) will be removed from cache after loading it (default: 1440)
|
--node-cache-lifetime= nodes with last update older than this time (in minutes) will be removed from cache after loading it
|
||||||
--node-cache-info show red and cyan 'x' characters in routes to indicate node cache misses and hits respectively
|
--node-cache-info show red and cyan 'x' characters in routes to indicate node cache misses and hits respectively
|
||||||
--timeout-rebalance= max rebalance session time in minutes
|
--timeout-rebalance= max rebalance session time in minutes
|
||||||
--timeout-attempt= max attempt time in minutes
|
--timeout-attempt= max attempt time in minutes
|
||||||
|
45
channels.go
45
channels.go
@ -63,10 +63,11 @@ func parseNodeChannelIDs(ids []string) (chans map[uint64]struct{}, nodes [][]byt
|
|||||||
func (r *regolancer) getChannelCandidates(fromPerc, toPerc, amount int64) error {
|
func (r *regolancer) getChannelCandidates(fromPerc, toPerc, amount int64) error {
|
||||||
|
|
||||||
for _, c := range r.channels {
|
for _, c := range r.channels {
|
||||||
|
|
||||||
if _, ok := r.excludeBoth[c.ChanId]; ok {
|
if _, ok := r.excludeBoth[c.ChanId]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := r.excludeIn[c.ChanId]; !ok {
|
if _, ok := r.excludeTo[c.ChanId]; !ok {
|
||||||
if _, ok := r.toChannelId[c.ChanId]; ok || len(r.toChannelId) == 0 {
|
if _, ok := r.toChannelId[c.ChanId]; ok || len(r.toChannelId) == 0 {
|
||||||
if c.LocalBalance < c.Capacity*toPerc/100 {
|
if c.LocalBalance < c.Capacity*toPerc/100 {
|
||||||
r.toChannels = append(r.toChannels, c)
|
r.toChannels = append(r.toChannels, c)
|
||||||
@ -74,7 +75,7 @@ func (r *regolancer) getChannelCandidates(fromPerc, toPerc, amount int64) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if _, ok := r.excludeOut[c.ChanId]; !ok {
|
if _, ok := r.excludeFrom[c.ChanId]; !ok {
|
||||||
if _, ok := r.fromChannelId[c.ChanId]; ok || len(r.fromChannelId) == 0 {
|
if _, ok := r.fromChannelId[c.ChanId]; ok || len(r.fromChannelId) == 0 {
|
||||||
if c.RemoteBalance < c.Capacity*fromPerc/100 {
|
if c.RemoteBalance < c.Capacity*fromPerc/100 {
|
||||||
r.fromChannels = append(r.fromChannels, c)
|
r.fromChannels = append(r.fromChannels, c)
|
||||||
@ -194,3 +195,43 @@ func parseScid(chanId string) int64 {
|
|||||||
return int64(scId.ToUint64())
|
return int64(scId.ToUint64())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *regolancer) getChannelForPeer(ctx context.Context, node []byte) []*lnrpc.Channel {
|
||||||
|
|
||||||
|
channels, err := r.lnClient.ListChannels(ctx, &lnrpc.ListChannelsRequest{ActiveOnly: true, PublicOnly: true, Peer: node})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error fetching channels when filtering for node \"%x\": %s", node, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return channels.Channels
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *regolancer) filterChannels(ctx context.Context, nodeChannelIDs []string) (channels map[uint64]struct{}) {
|
||||||
|
|
||||||
|
channels = map[uint64]struct{}{}
|
||||||
|
chans, nodes, err := parseNodeChannelIDs(nodeChannelIDs)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error parsing node/channel list:", err)
|
||||||
|
}
|
||||||
|
// Needed bc of deprecated ExcludeChannelsIn feature
|
||||||
|
for id := range chans {
|
||||||
|
if _, ok := channels[id]; !ok {
|
||||||
|
channels[id] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, node := range nodes {
|
||||||
|
chans := r.getChannelForPeer(ctx, node)
|
||||||
|
|
||||||
|
for _, c := range chans {
|
||||||
|
if _, ok := channels[c.ChanId]; !ok {
|
||||||
|
channels[c.ChanId] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
94
main.go
94
main.go
@ -38,8 +38,10 @@ type configParams struct {
|
|||||||
ProbeSteps int `short:"b" long:"probe-steps" description:"if the payment fails at the last hop try to probe lower amount using this many steps" json:"probe_steps" toml:"probe_steps"`
|
ProbeSteps int `short:"b" long:"probe-steps" description:"if the payment fails at the last hop try to probe lower amount using this many steps" json:"probe_steps" toml:"probe_steps"`
|
||||||
AllowRapidRebalance bool `long:"allow-rapid-rebalance" description:"if a rebalance succeeds the route will be used for further rebalances until criteria for channels is not satifsied" json:"allow_rapid_rebalance" toml:"allow_rapid_rebalance"`
|
AllowRapidRebalance bool `long:"allow-rapid-rebalance" description:"if a rebalance succeeds the route will be used for further rebalances until criteria for channels is not satifsied" json:"allow_rapid_rebalance" toml:"allow_rapid_rebalance"`
|
||||||
MinAmount int64 `long:"min-amount" description:"if probing is enabled this will be the minimum amount to try" json:"min_amount" toml:"min_amount"`
|
MinAmount int64 `long:"min-amount" description:"if probing is enabled this will be the minimum amount to try" json:"min_amount" toml:"min_amount"`
|
||||||
ExcludeChannelsIn []string `short:"i" long:"exclude-channel-in" description:"don't use this channel as incoming (can be specified multiple times)" json:"exclude_channels_in" toml:"exclude_channels_in"`
|
ExcludeChannelsIn []string `short:"i" long:"exclude-channel-in" description:"(DEPRECATED) don't use this channel as incoming (can be specified multiple times)" json:"exclude_channels_in" toml:"exclude_channels_in"`
|
||||||
ExcludeChannelsOut []string `short:"o" long:"exclude-channel-out" description:"don't use this channel as outgoing (can be specified multiple times)" json:"exclude_channels_out" toml:"exclude_channels_out"`
|
ExcludeChannelsOut []string `short:"o" long:"exclude-channel-out" description:"(DEPRECATED) don't use this channel as outgoing (can be specified multiple times)" json:"exclude_channels_out" toml:"exclude_channels_out"`
|
||||||
|
ExcludeFrom []string `long:"exclude-from" description:"don't use this node or channel as source (can be specified multiple times)" json:"exclude_from" toml:"exclude_from"`
|
||||||
|
ExcludeTo []string `long:"exclude-to" description:"don't use this node or channel as target (can be specified multiple times)" json:"exclude_to" toml:"exclude_to"`
|
||||||
ExcludeChannels []string `short:"e" long:"exclude-channel" description:"(DEPRECATED) don't use this channel at all (can be specified multiple times)" json:"exclude_channels" toml:"exclude_channels"`
|
ExcludeChannels []string `short:"e" long:"exclude-channel" description:"(DEPRECATED) don't use this channel at all (can be specified multiple times)" json:"exclude_channels" toml:"exclude_channels"`
|
||||||
ExcludeNodes []string `short:"d" long:"exclude-node" description:"(DEPRECATED) don't use this node for routing (can be specified multiple times)" json:"exclude_nodes" toml:"exclude_nodes"`
|
ExcludeNodes []string `short:"d" long:"exclude-node" description:"(DEPRECATED) don't use this node for routing (can be specified multiple times)" json:"exclude_nodes" toml:"exclude_nodes"`
|
||||||
Exclude []string `long:"exclude" description:"don't use this node or your channel for routing (can be specified multiple times)" json:"exclude" toml:"exclude"`
|
Exclude []string `long:"exclude" description:"don't use this node or your channel for routing (can be specified multiple times)" json:"exclude" toml:"exclude"`
|
||||||
@ -89,8 +91,8 @@ type regolancer struct {
|
|||||||
nodeCache map[string]cachedNodeInfo
|
nodeCache map[string]cachedNodeInfo
|
||||||
chanCache map[uint64]*lnrpc.ChannelEdge
|
chanCache map[uint64]*lnrpc.ChannelEdge
|
||||||
failureCache map[string]failedRoute
|
failureCache map[string]failedRoute
|
||||||
excludeIn map[uint64]struct{}
|
excludeTo map[uint64]struct{}
|
||||||
excludeOut map[uint64]struct{}
|
excludeFrom map[uint64]struct{}
|
||||||
excludeBoth map[uint64]struct{}
|
excludeBoth map[uint64]struct{}
|
||||||
excludeNodes [][]byte
|
excludeNodes [][]byte
|
||||||
statFilename string
|
statFilename string
|
||||||
@ -407,39 +409,43 @@ func preflightChecks(params *configParams) error {
|
|||||||
|
|
||||||
if (params.RelAmountFrom > 0 || params.RelAmountTo > 0) && params.AllowRapidRebalance {
|
if (params.RelAmountFrom > 0 || params.RelAmountTo > 0) && params.AllowRapidRebalance {
|
||||||
return fmt.Errorf("use either relative amounts or rapid rebalance but not both")
|
return fmt.Errorf("use either relative amounts or rapid rebalance but not both")
|
||||||
|
|
||||||
}
|
}
|
||||||
if params.NodeCacheLifetime == 0 {
|
if params.NodeCacheLifetime == 0 {
|
||||||
params.NodeCacheLifetime = 1440
|
params.NodeCacheLifetime = 1440
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(params.ExcludeChannels) > 0 || len(params.ExcludeNodes) > 0 {
|
if len(params.ExcludeChannels) > 0 || len(params.ExcludeNodes) > 0 {
|
||||||
log.Print(infoColor("--exclude-channel and exclude_channel parameter are deprecated, use --exclude or exclude parameter instead for both channels and nodes"))
|
log.Print(infoColor("--exclude-channel and exclude_channel parameter are deprecated, use --exclude or exclude parameter instead for both channels and nodes"))
|
||||||
if len(params.Exclude) > 0 {
|
if len(params.Exclude) > 0 {
|
||||||
return fmt.Errorf("can't use --exclude and --exclude-channel/--exclude-node (or config parameters) at the same time")
|
return fmt.Errorf("can't use --exclude and --exclude-channel/--exclude-node (or config parameters) at the same time")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.AllowUnbalanceFrom || params.AllowUnbalanceTo {
|
if params.AllowUnbalanceFrom || params.AllowUnbalanceTo {
|
||||||
log.Print(infoColor("--allow-unbalance-from/to are deprecated and enabled by default, please remove them from your config or command line parameters"))
|
log.Print(infoColor("--allow-unbalance-from/to are deprecated and enabled by default, please remove them from your config or command line parameters"))
|
||||||
}
|
}
|
||||||
|
if len(params.ExcludeChannelsIn) > 0 {
|
||||||
|
log.Print(infoColor("--exclude-channel-in are deprecated use --exclude-to instead, please remove them from your config or command line parameters"))
|
||||||
|
if len(params.ExcludeTo) > 0 {
|
||||||
|
return fmt.Errorf("can't use --exclude-to and --exclude-channel-in (or config parameters) at the same time")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(params.ExcludeChannelsOut) > 0 {
|
||||||
|
log.Print(infoColor("--exclude-channel-out are deprecated use --exclude-from instead, please remove them from your config or command line parameters"))
|
||||||
|
if len(params.ExcludeFrom) > 0 {
|
||||||
|
return fmt.Errorf("can't use --exclude-from and --exclude-channel-out (or config parameters) at the same time")
|
||||||
|
}
|
||||||
|
}
|
||||||
if params.TimeoutAttempt == 0 {
|
if params.TimeoutAttempt == 0 {
|
||||||
params.TimeoutAttempt = 5
|
params.TimeoutAttempt = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.TimeoutRebalance == 0 {
|
if params.TimeoutRebalance == 0 {
|
||||||
params.TimeoutRebalance = 360
|
params.TimeoutRebalance = 360
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.TimeoutInfo == 0 {
|
if params.TimeoutInfo == 0 {
|
||||||
params.TimeoutInfo = 30
|
params.TimeoutInfo = 30
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.TimeoutRoute == 0 {
|
if params.TimeoutRoute == 0 {
|
||||||
params.TimeoutRoute = 30
|
params.TimeoutRoute = 30
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -506,67 +512,33 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error listing own channels: ", err)
|
log.Fatal("Error listing own channels: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(params.From) > 0 {
|
if len(params.From) > 0 {
|
||||||
chans, nodes, err := parseNodeChannelIDs(params.From)
|
r.fromChannelId = r.filterChannels(infoCtx, params.From)
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Error parsing source node/channel list:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.fromChannelId = chans
|
|
||||||
|
|
||||||
for _, node := range nodes {
|
|
||||||
|
|
||||||
channels, err := r.lnClient.ListChannels(infoCtx, &lnrpc.ListChannelsRequest{ActiveOnly: true, PublicOnly: true, Peer: node})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error fetching channels when filtering for source node \"%x\": %s", node, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range channels.Channels {
|
|
||||||
if _, ok := r.fromChannelId[c.ChanId]; !ok {
|
|
||||||
r.fromChannelId[c.ChanId] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(r.fromChannelId) == 0 {
|
if len(r.fromChannelId) == 0 {
|
||||||
log.Fatal("No source nodes/channels selected, check if the ID is correct and node is online")
|
log.Fatal("No source nodes/channels selected, check if the ID is correct and node is online")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if len(params.To) > 0 {
|
if len(params.To) > 0 {
|
||||||
chans, nodes, err := parseNodeChannelIDs(params.To)
|
r.toChannelId = r.filterChannels(infoCtx, params.To)
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Error parsing target node/channel list:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.toChannelId = chans
|
|
||||||
|
|
||||||
for _, node := range nodes {
|
|
||||||
|
|
||||||
channels, err := r.lnClient.ListChannels(infoCtx, &lnrpc.ListChannelsRequest{ActiveOnly: true, PublicOnly: true, Peer: node})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error fetching channels when filtering for target node \"%x\": %s", node, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range channels.Channels {
|
|
||||||
if _, ok := r.toChannelId[c.ChanId]; !ok {
|
|
||||||
r.toChannelId[c.ChanId] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(r.toChannelId) == 0 {
|
if len(r.toChannelId) == 0 {
|
||||||
log.Fatal("No target nodes/channels selected, check if the ID is correct and node is online")
|
log.Fatal("No target nodes/channels selected, check if the ID is correct and node is online")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.excludeIn = makeChanSet(convertChanStringToInt(params.ExcludeChannelsIn))
|
if len(params.ExcludeFrom) > 0 {
|
||||||
r.excludeOut = makeChanSet(convertChanStringToInt(params.ExcludeChannelsOut))
|
r.excludeFrom = r.filterChannels(infoCtx, params.ExcludeFrom)
|
||||||
r.excludeBoth = makeChanSet(convertChanStringToInt(params.ExcludeChannels))
|
} else {
|
||||||
|
r.excludeFrom = makeChanSet(convertChanStringToInt(params.ExcludeChannelsOut))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(params.ExcludeTo) > 0 {
|
||||||
|
r.excludeTo = r.filterChannels(infoCtx, params.ExcludeTo)
|
||||||
|
} else {
|
||||||
|
r.excludeTo = makeChanSet(convertChanStringToInt(params.ExcludeChannelsIn))
|
||||||
|
}
|
||||||
|
|
||||||
|
r.excludeBoth = makeChanSet(convertChanStringToInt(params.ExcludeChannels))
|
||||||
err = r.makeNodeList(params.ExcludeNodes)
|
err = r.makeNodeList(params.ExcludeNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error parsing excluded node list: ", err)
|
log.Fatal("Error parsing excluded node list: ", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user