mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-18 17:45:48 +00:00
fix(gateway_balances): handle overflow exception: (#4355)
* Prevent internal error by catching overflow exception in `gateway_balances`. * Treat `gateway_balances` obligations overflow as max (largest valid) `STAmount`. * Note that very large sums of STAmount are approximations regardless. --------- Co-authored-by: Scott Schurr <scott@ripple.com>
This commit is contained in:
@@ -184,7 +184,23 @@ doGatewayBalances(RPC::JsonContext& context)
|
||||
bal = -rs->getBalance();
|
||||
}
|
||||
else
|
||||
bal -= rs->getBalance();
|
||||
{
|
||||
try
|
||||
{
|
||||
bal -= rs->getBalance();
|
||||
}
|
||||
catch (std::runtime_error const&)
|
||||
{
|
||||
// Presumably the exception was caused by overflow.
|
||||
// On overflow return the largest valid STAmount.
|
||||
// Very large sums of STAmount are approximations
|
||||
// anyway.
|
||||
bal = STAmount(
|
||||
bal.issue(),
|
||||
STAmount::cMaxValue,
|
||||
STAmount::cMaxOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -148,6 +148,60 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testGWBOverflow()
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
using namespace jtx;
|
||||
Env env(*this);
|
||||
|
||||
// Gateway account and assets
|
||||
Account const alice{"alice"};
|
||||
env.fund(XRP(10000), alice);
|
||||
env.close();
|
||||
auto USD = alice["USD"];
|
||||
|
||||
// The largest valid STAmount of USD:
|
||||
STAmount const maxUSD(
|
||||
USD.issue(), STAmount::cMaxValue, STAmount::cMaxOffset);
|
||||
|
||||
// Create a hotwallet
|
||||
Account const hw{"hw"};
|
||||
env.fund(XRP(10000), hw);
|
||||
env(trust(hw, maxUSD));
|
||||
env.close();
|
||||
env(pay(alice, hw, maxUSD));
|
||||
|
||||
// Create some clients
|
||||
Account const bob{"bob"};
|
||||
env.fund(XRP(10000), bob);
|
||||
env(trust(bob, maxUSD));
|
||||
env.close();
|
||||
env(pay(alice, bob, maxUSD));
|
||||
|
||||
Account const charley{"charley"};
|
||||
env.fund(XRP(10000), charley);
|
||||
env(trust(charley, maxUSD));
|
||||
env.close();
|
||||
env(pay(alice, charley, maxUSD));
|
||||
|
||||
env.close();
|
||||
|
||||
auto wsc = makeWSClient(env.app().config());
|
||||
|
||||
Json::Value query;
|
||||
query[jss::account] = alice.human();
|
||||
query[jss::hotwallet] = hw.human();
|
||||
|
||||
// Note that the sum of bob's and charley's USD balances exceeds
|
||||
// the amount that can be represented in an STAmount. Nevertheless
|
||||
// we get a valid "obligations" that shows the maximum valid
|
||||
// STAmount.
|
||||
auto jv = wsc->invoke("gateway_balances", query);
|
||||
expect(jv[jss::status] == "success");
|
||||
expect(jv[jss::result][jss::obligations]["USD"] == maxUSD.getText());
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
@@ -155,6 +209,8 @@ public:
|
||||
auto const sa = supported_amendments();
|
||||
testGWB(sa - featureFlowCross);
|
||||
testGWB(sa);
|
||||
|
||||
testGWBOverflow();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user