mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-20 02:25:53 +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();
|
bal = -rs->getBalance();
|
||||||
}
|
}
|
||||||
else
|
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
|
void
|
||||||
run() override
|
run() override
|
||||||
{
|
{
|
||||||
@@ -155,6 +209,8 @@ public:
|
|||||||
auto const sa = supported_amendments();
|
auto const sa = supported_amendments();
|
||||||
testGWB(sa - featureFlowCross);
|
testGWB(sa - featureFlowCross);
|
||||||
testGWB(sa);
|
testGWB(sa);
|
||||||
|
|
||||||
|
testGWBOverflow();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user