From 2de57135055d03c96a26d6ca4a0419095b2bf3ca Mon Sep 17 00:00:00 2001 From: Animesh Bilthare Date: Thu, 31 Oct 2024 11:11:29 +0530 Subject: [PATCH] cmd/commands: add validation for MPP parameters Adds validation to ensure that the combination of max_parts and max_shard_size_msat parameters can accommodate the full payment amount before attempting the payment. This prevents payments from entering a path finding loop that would eventually timeout when parameters are incompatible. --- lnrpc/routerrpc/router_backend.go | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/lnrpc/routerrpc/router_backend.go b/lnrpc/routerrpc/router_backend.go index f2d21750ae..402c9296e9 100644 --- a/lnrpc/routerrpc/router_backend.go +++ b/lnrpc/routerrpc/router_backend.go @@ -800,6 +800,30 @@ func (r *RouterBackend) UnmarshallRoute(rpcroute *lnrpc.Route) ( return route, nil } +// maybeValidateMPPParams validates that the MPP parameters are compatible with the +// payment amount. It returns an error if the parameters don't allow the full +// payment amount to be sent. +// maybeValidateMPPParams could be enhanced with additional checks +func maybeValidateMPPParams(amt lnwire.MilliSatoshi, maxParts uint32, + maxShardSize lnwire.MilliSatoshi) error { + + // Early return if MPP is not being used + if maxShardSize == 0 { + return nil + } + + // Calculate maximum possible amount + maxPossibleAmount := lnwire.MilliSatoshi(maxParts) * maxShardSize + + if amt > maxPossibleAmount { + return fmt.Errorf("payment amount %v exceeds maximum possible "+ + "amount %v with max_parts=%v and max_shard_size_msat=%v", + amt, maxPossibleAmount, maxParts, maxShardSize) + } + + return nil +} + // extractIntentFromSendRequest attempts to parse the SendRequest details // required to dispatch a client from the information presented by an RPC // client. @@ -1174,7 +1198,11 @@ func (r *RouterBackend) extractIntentFromSendRequest( payIntent.DestFeatures = features } - + err = maybeValidateMPPParams( + payIntent.Amount, maxParts, lnwire.MilliSatoshi(rpcPayReq.MaxShardSizeMsat)) + if err != nil { + return nil, fmt.Errorf("invalid MPP parameters: %v", err) + } // Do bounds checking with the block padding so the router isn't // left with a zombie payment in case the user messes up. err = routing.ValidateCLTVLimit(