diff --git a/mission_ctl.go b/mission_ctl.go index 16aea01..6a4eb51 100644 --- a/mission_ctl.go +++ b/mission_ctl.go @@ -1,8 +1,10 @@ package main import ( + "context" "encoding/hex" "fmt" + "math" "github.com/lightningnetwork/lnd/lnrpc" ) @@ -31,3 +33,29 @@ func (r *regolancer) validateRoute(route *lnrpc.Route) error { } return nil } + +func (r *regolancer) maxAmountOnRoute(ctx context.Context, route *lnrpc.Route) (uint64, error) { + var capAmountMsat uint64 = math.MaxInt64 + for _, h := range route.Hops { + edge, err := r.getChanInfo(ctx, h.ChanId) + if err != nil { + return 0, err + } + + policyTo := edge.Node1Policy + if h.PubKey != edge.Node2Pub { + policyTo = edge.Node2Policy + } + + if policyTo.MaxHtlcMsat <= 0 { + continue + } + + if capAmountMsat > policyTo.MaxHtlcMsat { + capAmountMsat = policyTo.MaxHtlcMsat + } + } + + return capAmountMsat, nil + +} diff --git a/rebalancer.go b/rebalancer.go index f1bb465..be03906 100644 --- a/rebalancer.go +++ b/rebalancer.go @@ -95,10 +95,12 @@ func (r *regolancer) tryRapidRebalance(ctx context.Context, route *lnrpc.Route) // Need to save the route and amount locally because we are changing it via the accelerator // In case we reuse the route it will lead to a situation where no route is found // the route variable will be overwritten and we are loosing the information - routeLocal *lnrpc.Route - amtLocal int64 - accelerator int64 = 1 - hittingTheWall bool + routeLocal *lnrpc.Route + amtLocal int64 = amt + accelerator int64 = 1 + hittingTheWall bool + capReached bool + maxAmountOnRouteMsat uint64 ) result.successfulAttempts = 0 @@ -106,24 +108,39 @@ func (r *regolancer) tryRapidRebalance(ctx context.Context, route *lnrpc.Route) result.successfulAmt = amt result.paidFeeMsat = route.TotalFeesMsat + maxAmountOnRouteMsat, err = r.maxAmountOnRoute(ctx, route) + if err != nil { + return result, err + } + for { if hittingTheWall { accelerator >>= 1 - // In case we enounter that we are already constrained + // In case we encounter that we are already constrained // by the liquidity on the channels we are waiting for // the accelerator to go below this amount to save // already failed rebalances if amtLocal < accelerator*amt && amtLocal > 0 { continue } - } else { + } else if !capReached { + // we only increase the amount if the max Amount on the + // route is still not reached accelerator <<= 1 } - amtLocal = accelerator * amt + + if uint64(accelerator*amt) < maxAmountOnRouteMsat/1000 { + amtLocal = accelerator * amt + } else if !capReached { + capReached = true + log.Printf("Max amount on route reached capping amount at %s sats "+ + "| max amount on route (max htlc size) %s sats\n", infoColor(amtLocal), infoColor(maxAmountOnRouteMsat/1000)) + } if accelerator < 1 { break } + log.Printf("Rapid rebalance attempt %s, amount: %s\n", hiWhiteColor(result.successfulAttempts+1), hiWhiteColor(amtLocal)) cTo, err := r.getChanInfo(ctx, to)