From 976bfe8c14cb2c8ef5aa1b870a2fcf139f8bbeaa Mon Sep 17 00:00:00 2001 From: rkfg Date: Mon, 7 Nov 2022 18:08:52 +0300 Subject: [PATCH] Make timeouts customizable --- README.md | 11 ++++++++--- channels.go | 2 +- config.json.sample | 6 +++++- config.toml.sample | 7 ++++++- main.go | 30 +++++++++++++++++++++++++----- payment.go | 2 +- routes.go | 2 +- 7 files changed, 47 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 61cc08c..59b8a22 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,10 @@ rebalance-lnd](https://github.com/accumulator/rebalance-lnd). # Features - automatically pick source and target channel by local/remote liquidity ratio -- retry indefinitely until it succeeds or 6 hours pass (currently hardcoded) -- payments time out after 5 minutes (currently hardcoded) so if something's - stuck the process will continue shortly +- retry indefinitely until it succeeds or 6 hours pass (by default) +- payments time out after 5 minutes (by default) so if something's stuck the + process will continue shortly +- timeouts can be customized - JSON/TOML config file to set some defaults you prefer - optional route probing using binary search to rebalance a smaller amount - optional rapid rebalancing using the same route for further rebalances @@ -94,6 +95,10 @@ in `~/go/bin/linux_arm`. --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-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-attempt= max attempt time in minutes + --timeout-info= max general info query time (local channels, node id etc.) in seconds + --timeout-route= max channel selection and route query time in seconds -v, --version show program version and exit ``` diff --git a/channels.go b/channels.go index 6250899..5a7aaf9 100644 --- a/channels.go +++ b/channels.go @@ -21,7 +21,7 @@ func formatChannelPair(a, b uint64) string { } func (r *regolancer) getChannels(ctx context.Context) error { - ctx, cancel := context.WithTimeout(ctx, time.Second*30) + ctx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(params.TimeoutRoute)) defer cancel() channels, err := r.lnClient.ListChannels(ctx, &lnrpc.ListChannelsRequest{ActiveOnly: true, PublicOnly: true}) if err != nil { diff --git a/config.json.sample b/config.json.sample index 3ca2f48..68f50ef 100644 --- a/config.json.sample +++ b/config.json.sample @@ -36,5 +36,9 @@ "821280210373779139", "757806x673x1", "03cde60a6323f7122d5178255766e38114b4722ede08f7c9e0c5df9b912cc201d6" - ] + ], + "timeout_rebalance": 360, + "timeout_attempt": 5, + "timeout_info": 30, + "timeout_route": 30 } \ No newline at end of file diff --git a/config.toml.sample b/config.toml.sample index c909562..e76c999 100644 --- a/config.toml.sample +++ b/config.toml.sample @@ -46,4 +46,9 @@ lost_profit = true "821280210377179137", "821280210377179136", "03271338633d2d37b285dae4df40b413d8c6c791fbee7797bc5dc70812196d7d5c" -] \ No newline at end of file +] + +timeout_rebalance = 360 +timeout_attempt = 5 +timeout_info = 30 +timeout_route = 30 diff --git a/main.go b/main.go index 19f0971..a813056 100644 --- a/main.go +++ b/main.go @@ -54,6 +54,10 @@ type configParams struct { NodeCacheFilename string `long:"node-cache-filename" description:"save and load other nodes information to this file, improves cold start performance" json:"node_cache_filename" toml:"node_cache_filename"` NodeCacheLifetime int `long:"node-cache-lifetime" description:"nodes with last update older than this time (in minutes) will be removed from cache after loading it" json:"node_cache_lifetime" toml:"node_cache_lifetime"` NodeCacheInfo bool `long:"node-cache-info" description:"show red and cyan 'x' characters in routes to indicate node cache misses and hits respectively" json:"node_cache_info" toml:"node_cache_info"` + TimeoutRebalance int `long:"timeout-rebalance" description:"max rebalance session time in minutes" json:"timeout_rebalance" toml:"timeout_rebalance"` + TimeoutAttempt int `long:"timeout-attempt" description:"max attempt time in minutes" json:"timeout_attempt" toml:"timeout_attempt"` + TimeoutInfo int `long:"timeout-info" description:"max general info query time (local channels, node id etc.) in seconds" json:"timeout_info" toml:"timeout_info"` + TimeoutRoute int `long:"timeout-route" description:"max channel selection and route query time in seconds" json:"timeout_route" toml:"timeout_route"` Version bool `short:"v" long:"version" description:"show program version and exit"` } @@ -159,7 +163,7 @@ func convertChanStringToInt(chanIds []string) (channels []uint64) { func tryRebalance(ctx context.Context, r *regolancer, attempt *int) (err error, repeat bool) { - attemptCtx, attemptCancel := context.WithTimeout(ctx, time.Minute*5) + attemptCtx, attemptCancel := context.WithTimeout(ctx, time.Minute*time.Duration(params.TimeoutAttempt)) defer attemptCancel() @@ -168,7 +172,7 @@ func tryRebalance(ctx context.Context, r *regolancer, attempt *int) (err error, log.Printf(errColor("Error during picking channel: %s"), err) return err, false } - routeCtx, routeCtxCancel := context.WithTimeout(attemptCtx, time.Second*30) + routeCtx, routeCtxCancel := context.WithTimeout(attemptCtx, time.Second*time.Duration(params.TimeoutRoute)) defer routeCtxCancel() routes, fee, err := r.getRoutes(routeCtx, from, to, amt*1000) if err != nil { @@ -327,7 +331,7 @@ func tryRapidRebalance(ctx context.Context, r *regolancer, from, to uint64, rout return rapidAttempt, err } - attemptCtx, attemptCancel := context.WithTimeout(ctx, time.Minute*5) + attemptCtx, attemptCancel := context.WithTimeout(ctx, time.Minute*time.Duration(params.TimeoutAttempt)) defer attemptCancel() @@ -417,6 +421,22 @@ func preflightChecks(params *configParams) error { log.Print(infoColor("--allow-unbalance-from/to are deprecated and enabled by default, please remove them from your config or command line parameters")) } + if params.TimeoutAttempt == 0 { + params.TimeoutAttempt = 5 + } + + if params.TimeoutRebalance == 0 { + params.TimeoutRebalance = 360 + } + + if params.TimeoutInfo == 0 { + params.TimeoutInfo = 30 + } + + if params.TimeoutRoute == 0 { + params.TimeoutRoute = 30 + } + return nil } @@ -450,9 +470,9 @@ func main() { } r.lnClient = lnrpc.NewLightningClient(conn) r.routerClient = routerrpc.NewRouterClient(conn) - mainCtx, mainCtxCancel := context.WithTimeout(context.Background(), time.Hour*6) + mainCtx, mainCtxCancel := context.WithTimeout(context.Background(), time.Minute*time.Duration(params.TimeoutRebalance)) defer mainCtxCancel() - infoCtx, infoCtxCancel := context.WithTimeout(mainCtx, time.Second*30) + infoCtx, infoCtxCancel := context.WithTimeout(mainCtx, time.Second*time.Duration(params.TimeoutInfo)) defer infoCtxCancel() info, err := r.lnClient.GetInfo(infoCtx, &lnrpc.GetInfoRequest{}) if err != nil { diff --git a/payment.go b/payment.go index 9150f61..dc14345 100644 --- a/payment.go +++ b/payment.go @@ -81,7 +81,7 @@ func (r *regolancer) pay(ctx context.Context, amount int64, minAmount int64, } prevHop := route.Hops[result.Failure.FailureSourceIndex-1] failedHop := route.Hops[result.Failure.FailureSourceIndex] - nodeCtx, cancel := context.WithTimeout(ctx, time.Minute) + nodeCtx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(params.TimeoutInfo)) defer cancel() node1, err := r.getNodeInfo(nodeCtx, prevHop.PubKey) node1name := "" diff --git a/routes.go b/routes.go index b87c45b..af50366 100644 --- a/routes.go +++ b/routes.go @@ -89,7 +89,7 @@ func (r *regolancer) calcFeeMsat(ctx context.Context, from, to uint64, } func (r *regolancer) getRoutes(ctx context.Context, from, to uint64, amtMsat int64) ([]*lnrpc.Route, int64, error) { - routeCtx, cancel := context.WithTimeout(ctx, time.Second*30) + routeCtx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(params.TimeoutRoute)) defer cancel() feeMsat, lastPKstr, err := r.calcFeeMsat(routeCtx, from, to, amtMsat) if err != nil {