From 79417ac59a037bc39a11a6a53512db02e9a1b858 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 3 Mar 2015 14:01:38 -0800 Subject: [PATCH] Limit passes in the payment engine to prevent endless looping: This adds a limit of 1,000 passes to the payment engine. It protects against possible cases where the execution of a pass fails to exhaust the liquidity that made the pass possible or cases where two passes alternate providing liquidity for each other. --- src/ripple/app/paths/RippleCalc.cpp | 14 +++++++++++++- src/ripple/app/paths/Tuning.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/ripple/app/paths/RippleCalc.cpp b/src/ripple/app/paths/RippleCalc.cpp index 0c2e8e71d..446521539 100644 --- a/src/ripple/app/paths/RippleCalc.cpp +++ b/src/ripple/app/paths/RippleCalc.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include #include #include #include @@ -295,11 +296,12 @@ TER RippleCalc::rippleCalculate () } } + ++iPass; if (ShouldLog (lsDEBUG, RippleCalc)) { WriteLog (lsDEBUG, RippleCalc) << "rippleCalc: Summary:" - << " Pass: " << ++iPass + << " Pass: " << iPass << " Dry: " << iDry << " Paths: " << pathStateList_.size (); for (auto pathState: pathStateList_) @@ -374,6 +376,16 @@ TER RippleCalc::rippleCalculate () mumSource_.insert ( pathState->reverse().begin (), pathState->reverse().end ()); + if (iPass >= PAYMENT_MAX_LOOPS) + { + // This payment is taking too many passes + + WriteLog (lsERROR, RippleCalc) + << "rippleCalc: pass limit"; + + resultCode = telFAILED_PROCESSING; + } + } else if (!inputFlags.partialPaymentAllowed) { diff --git a/src/ripple/app/paths/Tuning.h b/src/ripple/app/paths/Tuning.h index d786502df..d498459ad 100644 --- a/src/ripple/app/paths/Tuning.h +++ b/src/ripple/app/paths/Tuning.h @@ -24,6 +24,7 @@ namespace ripple { int const CALC_NODE_DELIVER_MAX_LOOPS = 40; int const NODE_ADVANCE_MAX_LOOPS = 100; +int const PAYMENT_MAX_LOOPS = 1000; int const PATHFINDER_HIGH_PRIORITY = 100000; int const PATHFINDER_MAX_PATHS = 50; int const PATHFINDER_MAX_COMPLETE_PATHS = 1000;