Merge pull request #30 from ziggie1984/ctx_separation

pull/33/head
rkfg 2 years ago committed by GitHub
commit bb98d0889b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -159,12 +159,16 @@ 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)
defer attemptCancel()
from, to, amt, err := r.pickChannelPair(params.Amount, params.MinAmount, params.RelAmountFrom, params.RelAmountTo)
if err != nil {
log.Printf(errColor("Error during picking channel: %s"), err)
return err, false
}
routeCtx, routeCtxCancel := context.WithTimeout(ctx, time.Second*30)
routeCtx, routeCtxCancel := context.WithTimeout(attemptCtx, time.Second*30)
defer routeCtxCancel()
routes, fee, err := r.getRoutes(routeCtx, from, to, amt*1000)
if err != nil {
@ -179,8 +183,8 @@ func tryRebalance(ctx context.Context, r *regolancer, attempt *int) (err error,
for _, route := range routes {
log.Printf("Attempt %s, amount: %s (max fee: %s sat | %s ppm )",
hiWhiteColorF("#%d", *attempt), hiWhiteColor(amt), formatFee(fee), formatFeePPM(amt*1000, fee))
r.printRoute(ctx, route)
err = r.pay(ctx, amt, params.MinAmount, route, params.ProbeSteps)
r.printRoute(attemptCtx, route)
err = r.pay(attemptCtx, amt, params.MinAmount, route, params.ProbeSteps)
if err == nil {
if params.AllowRapidRebalance {
@ -198,7 +202,7 @@ func tryRebalance(ctx context.Context, r *regolancer, attempt *int) (err error,
if retryErr, ok := err.(ErrRetry); ok {
amt = retryErr.amount
log.Printf("Trying to rebalance again with %s", hiWhiteColor(amt))
probedRoute, err := r.rebuildRoute(ctx, route, amt)
probedRoute, err := r.rebuildRoute(attemptCtx, route, amt)
if err != nil {
log.Printf("Error rebuilding the route for probed payment: %s", errColor(err))
} else {
@ -223,6 +227,11 @@ func tryRebalance(ctx context.Context, r *regolancer, attempt *int) (err error,
}
*attempt++
}
attemptCancel()
if attemptCtx.Err() == context.DeadlineExceeded {
log.Print(errColor("Attempt timed out"))
}
return nil, true
}
@ -318,7 +327,18 @@ func tryRapidRebalance(ctx context.Context, r *regolancer, from, to uint64, rout
return rapidAttempt, err
}
err = r.pay(ctx, amt, params.MinAmount, route, 0)
attemptCtx, attemptCancel := context.WithTimeout(ctx, time.Minute*5)
defer attemptCancel()
err = r.pay(attemptCtx, amt, params.MinAmount, route, 0)
attemptCancel()
if attemptCtx.Err() == context.DeadlineExceeded {
log.Print(errColor("Rapid rebalance attempt timed out"))
return rapidAttempt, attemptCtx.Err()
}
if err != nil {
log.Printf("Rebalance failed with %s", err)
@ -535,12 +555,7 @@ func main() {
}()
for {
attemptCtx, attemptCancel := context.WithTimeout(mainCtx, time.Minute*5)
_, retry := tryRebalance(attemptCtx, &r, &attempt)
attemptCancel()
if attemptCtx.Err() == context.DeadlineExceeded {
log.Print(errColor("Attempt timed out"))
}
_, retry := tryRebalance(mainCtx, &r, &attempt)
if mainCtx.Err() == context.DeadlineExceeded {
log.Println(errColor("Rebalancing timed out"))
return

@ -108,11 +108,13 @@ func (r *regolancer) pay(ctx context.Context, amount int64, minAmount int64,
min := int64(0)
start := amount / 2
if minAmount > 0 && minAmount < amount {
// need to use -1 so we do not fail the first probing attempt
min = -minAmount - 1
start = minAmount
}
maxAmount, err := r.probeRoute(ctx, route, min, amount, start,
probeSteps)
if err != nil {
logErrorF("Probe error: %s", err)
return err

@ -80,7 +80,7 @@ func (r *regolancer) calcEconFeeMsat(ctx context.Context, from, to uint64, amtMs
}
func (r *regolancer) calcFeeMsat(ctx context.Context, from, to uint64,
amtMsat int64, ratio float64) (feeMsat int64, lastPKstr string, err error) {
amtMsat int64) (feeMsat int64, lastPKstr string, err error) {
if params.FeeLimitPPM > 0 {
return r.calcFeeLimitMsat(ctx, to, amtMsat, params.FeeLimitPPM)
} else {
@ -91,8 +91,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)
defer cancel()
feeMsat, lastPKstr, err := r.calcFeeMsat(routeCtx, from, to, amtMsat,
params.EconRatio)
feeMsat, lastPKstr, err := r.calcFeeMsat(routeCtx, from, to, amtMsat)
if err != nil {
return nil, 0, err
}
@ -195,25 +194,32 @@ func (r *regolancer) rebuildRoute(ctx context.Context, route *lnrpc.Route, amoun
func (r *regolancer) probeRoute(ctx context.Context, route *lnrpc.Route,
goodAmount, badAmount, amount int64, steps int) (maxAmount int64, err error) {
if absoluteDeltaPPM(badAmount, amount) <= params.FailTolerance || absoluteDeltaPPM(amount, goodAmount) <= params.FailTolerance || amount == -goodAmount {
defer func() {
if ctx.Err() == context.DeadlineExceeded && goodAmount > 0 {
maxAmount = goodAmount
log.Printf("Probing timed out with value %s", hiWhiteColor(maxAmount))
}
}()
if absoluteDeltaPPM(badAmount, amount) <= params.FailTolerance || absoluteDeltaPPM(amount, goodAmount) <= params.FailTolerance || amount == -goodAmount {
bestAmount := hiWhiteColor(goodAmount)
if goodAmount <= 0 {
bestAmount = hiWhiteColor("unknown")
goodAmount = 0
}
log.Printf("Best amount is %s", bestAmount)
return goodAmount, nil
return
}
probedRoute, err := r.rebuildRoute(ctx, route, amount)
if err != nil {
return 0, err
return
}
maxFeeMsat, _, err := r.calcFeeMsat(ctx, probedRoute.Hops[0].ChanId,
probedRoute.Hops[len(probedRoute.Hops)-1].ChanId, amount*1000,
params.EconRatio)
probedRoute.Hops[len(probedRoute.Hops)-1].ChanId, amount*1000)
if err != nil {
return 0, err
return
}
if probedRoute.TotalFeesMsat > maxFeeMsat {
nextAmount := amount + (badAmount-amount)/2
@ -242,7 +248,8 @@ func (r *regolancer) probeRoute(ctx context.Context, route *lnrpc.Route,
if result.Failure.Code == lnrpc.Failure_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS { // payment can succeed
if steps == 1 {
log.Printf("best amount is %s", hiWhiteColor(amount))
return amount, nil
goodAmount = amount
return
}
nextAmount := amount + (badAmount-amount)/2
log.Printf("%s is good enough, trying amount %s, %s steps left",
@ -260,7 +267,7 @@ func (r *regolancer) probeRoute(ctx context.Context, route *lnrpc.Route,
}
log.Printf("%s is too much, best amount is %s",
hiWhiteColor(amount), bestAmount)
return goodAmount, nil
return
}
var nextAmount int64
if goodAmount >= 0 {

Loading…
Cancel
Save