mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-02 00:45:58 +00:00
Merge branch 'master' into develop
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
#define RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED
|
#define RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED
|
||||||
|
|
||||||
#include <xrpl/basics/contract.h>
|
#include <xrpl/basics/contract.h>
|
||||||
|
#include <xrpl/protocol/detail/token_errors.h>
|
||||||
|
|
||||||
#include <boost/outcome.hpp>
|
#include <boost/outcome.hpp>
|
||||||
#include <boost/outcome/result.hpp>
|
#include <boost/outcome/result.hpp>
|
||||||
@@ -71,12 +72,12 @@ carrying_add(std::uint64_t a, std::uint64_t b)
|
|||||||
// (i.e a[0] is the 2^0 coefficient, a[n] is the 2^(64*n) coefficient)
|
// (i.e a[0] is the 2^0 coefficient, a[n] is the 2^(64*n) coefficient)
|
||||||
// panics if overflows (this is a specialized adder for b58 decoding.
|
// panics if overflows (this is a specialized adder for b58 decoding.
|
||||||
// it should never overflow).
|
// it should never overflow).
|
||||||
inline void
|
[[nodiscard]] inline TokenCodecErrc
|
||||||
inplace_bigint_add(std::span<std::uint64_t> a, std::uint64_t b)
|
inplace_bigint_add(std::span<std::uint64_t> a, std::uint64_t b)
|
||||||
{
|
{
|
||||||
if (a.size() <= 1)
|
if (a.size() <= 1)
|
||||||
{
|
{
|
||||||
ripple::LogicError("Input span too small for inplace_bigint_add");
|
return TokenCodecErrc::inputTooSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint64_t carry;
|
std::uint64_t carry;
|
||||||
@@ -86,28 +87,29 @@ inplace_bigint_add(std::span<std::uint64_t> a, std::uint64_t b)
|
|||||||
{
|
{
|
||||||
if (!carry)
|
if (!carry)
|
||||||
{
|
{
|
||||||
return;
|
return TokenCodecErrc::success;
|
||||||
}
|
}
|
||||||
std::tie(v, carry) = carrying_add(v, 1);
|
std::tie(v, carry) = carrying_add(v, 1);
|
||||||
}
|
}
|
||||||
if (carry)
|
if (carry)
|
||||||
{
|
{
|
||||||
LogicError("Overflow in inplace_bigint_add");
|
return TokenCodecErrc::overflowAdd;
|
||||||
}
|
}
|
||||||
|
return TokenCodecErrc::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
[[nodiscard]] inline TokenCodecErrc
|
||||||
inplace_bigint_mul(std::span<std::uint64_t> a, std::uint64_t b)
|
inplace_bigint_mul(std::span<std::uint64_t> a, std::uint64_t b)
|
||||||
{
|
{
|
||||||
if (a.empty())
|
if (a.empty())
|
||||||
{
|
{
|
||||||
LogicError("Empty span passed to inplace_bigint_mul");
|
return TokenCodecErrc::inputTooSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const last_index = a.size() - 1;
|
auto const last_index = a.size() - 1;
|
||||||
if (a[last_index] != 0)
|
if (a[last_index] != 0)
|
||||||
{
|
{
|
||||||
LogicError("Non-zero element in inplace_bigint_mul last index");
|
return TokenCodecErrc::inputTooLarge;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint64_t carry = 0;
|
std::uint64_t carry = 0;
|
||||||
@@ -116,7 +118,9 @@ inplace_bigint_mul(std::span<std::uint64_t> a, std::uint64_t b)
|
|||||||
std::tie(coeff, carry) = carrying_mul(coeff, b, carry);
|
std::tie(coeff, carry) = carrying_mul(coeff, b, carry);
|
||||||
}
|
}
|
||||||
a[last_index] = carry;
|
a[last_index] = carry;
|
||||||
|
return TokenCodecErrc::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// divide a "big uint" value inplace and return the mod
|
// divide a "big uint" value inplace and return the mod
|
||||||
// numerator is stored so smallest coefficients come first
|
// numerator is stored so smallest coefficients come first
|
||||||
[[nodiscard]] inline std::uint64_t
|
[[nodiscard]] inline std::uint64_t
|
||||||
@@ -166,11 +170,7 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
|
|||||||
b58_10_to_b58_be(std::uint64_t input)
|
b58_10_to_b58_be(std::uint64_t input)
|
||||||
{
|
{
|
||||||
constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10;
|
constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10;
|
||||||
if (input >= B_58_10)
|
assert(input < B_58_10);
|
||||||
{
|
|
||||||
LogicError("Input to b58_10_to_b58_be equals or exceeds 58^10.");
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr std::size_t resultSize = 10;
|
constexpr std::size_t resultSize = 10;
|
||||||
std::array<std::uint8_t, resultSize> result{};
|
std::array<std::uint8_t, resultSize> result{};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ enum class TokenCodecErrc {
|
|||||||
mismatchedTokenType,
|
mismatchedTokenType,
|
||||||
mismatchedChecksum,
|
mismatchedChecksum,
|
||||||
invalidEncodingChar,
|
invalidEncodingChar,
|
||||||
|
overflowAdd,
|
||||||
unknown,
|
unknown,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -467,6 +467,11 @@ b256_to_b58_be(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
static constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10;
|
||||||
|
if (base_58_10_coeff[i] >= B_58_10)
|
||||||
|
{
|
||||||
|
return Unexpected(TokenCodecErrc::inputTooLarge);
|
||||||
|
}
|
||||||
std::array<std::uint8_t, 10> const b58_be =
|
std::array<std::uint8_t, 10> const b58_be =
|
||||||
ripple::b58_fast::detail::b58_10_to_b58_be(base_58_10_coeff[i]);
|
ripple::b58_fast::detail::b58_10_to_b58_be(base_58_10_coeff[i]);
|
||||||
std::size_t to_skip = 0;
|
std::size_t to_skip = 0;
|
||||||
@@ -565,10 +570,23 @@ b58_to_b256_be(std::string_view input, std::span<std::uint8_t> out)
|
|||||||
for (int i = 1; i < num_b_58_10_coeffs; ++i)
|
for (int i = 1; i < num_b_58_10_coeffs; ++i)
|
||||||
{
|
{
|
||||||
std::uint64_t const c = b_58_10_coeff[i];
|
std::uint64_t const c = b_58_10_coeff[i];
|
||||||
ripple::b58_fast::detail::inplace_bigint_mul(
|
|
||||||
std::span(&result[0], cur_result_size + 1), B_58_10);
|
{
|
||||||
ripple::b58_fast::detail::inplace_bigint_add(
|
auto code = ripple::b58_fast::detail::inplace_bigint_mul(
|
||||||
std::span(&result[0], cur_result_size + 1), c);
|
std::span(&result[0], cur_result_size + 1), B_58_10);
|
||||||
|
if (code != TokenCodecErrc::success)
|
||||||
|
{
|
||||||
|
return Unexpected(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto code = ripple::b58_fast::detail::inplace_bigint_add(
|
||||||
|
std::span(&result[0], cur_result_size + 1), c);
|
||||||
|
if (code != TokenCodecErrc::success)
|
||||||
|
{
|
||||||
|
return Unexpected(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (result[cur_result_size] != 0)
|
if (result[cur_result_size] != 0)
|
||||||
{
|
{
|
||||||
cur_result_size += 1;
|
cur_result_size += 1;
|
||||||
|
|||||||
@@ -873,6 +873,25 @@ struct PayChan_test : public beast::unit_test::suite
|
|||||||
auto const chan1Str = to_string(channel(alice, bob, env.seq(alice)));
|
auto const chan1Str = to_string(channel(alice, bob, env.seq(alice)));
|
||||||
env(create(alice, bob, channelFunds, settleDelay, pk));
|
env(create(alice, bob, channelFunds, settleDelay, pk));
|
||||||
env.close();
|
env.close();
|
||||||
|
{
|
||||||
|
// test account non-string
|
||||||
|
auto testInvalidAccountParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::account] = param;
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json", "account_channels", to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'account'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidAccountParam(1);
|
||||||
|
testInvalidAccountParam(1.1);
|
||||||
|
testInvalidAccountParam(true);
|
||||||
|
testInvalidAccountParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::arrayValue));
|
||||||
|
}
|
||||||
{
|
{
|
||||||
auto const r =
|
auto const r =
|
||||||
env.rpc("account_channels", alice.human(), bob.human());
|
env.rpc("account_channels", alice.human(), bob.human());
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ class base58_test : public beast::unit_test::suite
|
|||||||
constexpr std::size_t iters = 100000;
|
constexpr std::size_t iters = 100000;
|
||||||
auto eng = randEngine();
|
auto eng = randEngine();
|
||||||
std::uniform_int_distribution<std::uint64_t> dist;
|
std::uniform_int_distribution<std::uint64_t> dist;
|
||||||
|
std::uniform_int_distribution<std::uint64_t> dist1(1);
|
||||||
for (int i = 0; i < iters; ++i)
|
for (int i = 0; i < iters; ++i)
|
||||||
{
|
{
|
||||||
std::uint64_t const d = dist(eng);
|
std::uint64_t const d = dist(eng);
|
||||||
@@ -209,12 +210,31 @@ class base58_test : public beast::unit_test::suite
|
|||||||
|
|
||||||
auto const refAdd = boostBigInt + d;
|
auto const refAdd = boostBigInt + d;
|
||||||
|
|
||||||
b58_fast::detail::inplace_bigint_add(
|
auto const result = b58_fast::detail::inplace_bigint_add(
|
||||||
std::span<uint64_t>(bigInt.data(), bigInt.size()), d);
|
std::span<uint64_t>(bigInt.data(), bigInt.size()), d);
|
||||||
|
BEAST_EXPECT(result == TokenCodecErrc::success);
|
||||||
auto const foundAdd = multiprecision_utils::toBoostMP(bigInt);
|
auto const foundAdd = multiprecision_utils::toBoostMP(bigInt);
|
||||||
BEAST_EXPECT(refAdd == foundAdd);
|
BEAST_EXPECT(refAdd == foundAdd);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < iters; ++i)
|
for (int i = 0; i < iters; ++i)
|
||||||
|
{
|
||||||
|
std::uint64_t const d = dist1(eng);
|
||||||
|
// Force overflow
|
||||||
|
std::vector<std::uint64_t> bigInt(
|
||||||
|
5, std::numeric_limits<std::uint64_t>::max());
|
||||||
|
|
||||||
|
auto const boostBigInt = multiprecision_utils::toBoostMP(
|
||||||
|
std::span<std::uint64_t>(bigInt.data(), bigInt.size()));
|
||||||
|
|
||||||
|
auto const refAdd = boostBigInt + d;
|
||||||
|
|
||||||
|
auto const result = b58_fast::detail::inplace_bigint_add(
|
||||||
|
std::span<uint64_t>(bigInt.data(), bigInt.size()), d);
|
||||||
|
BEAST_EXPECT(result == TokenCodecErrc::overflowAdd);
|
||||||
|
auto const foundAdd = multiprecision_utils::toBoostMP(bigInt);
|
||||||
|
BEAST_EXPECT(refAdd != foundAdd);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < iters; ++i)
|
||||||
{
|
{
|
||||||
std::uint64_t const d = dist(eng);
|
std::uint64_t const d = dist(eng);
|
||||||
auto bigInt = multiprecision_utils::randomBigInt(/* minSize */ 2);
|
auto bigInt = multiprecision_utils::randomBigInt(/* minSize */ 2);
|
||||||
@@ -226,11 +246,29 @@ class base58_test : public beast::unit_test::suite
|
|||||||
|
|
||||||
auto const refMul = boostBigInt * d;
|
auto const refMul = boostBigInt * d;
|
||||||
|
|
||||||
b58_fast::detail::inplace_bigint_mul(
|
auto const result = b58_fast::detail::inplace_bigint_mul(
|
||||||
std::span<uint64_t>(bigInt.data(), bigInt.size()), d);
|
std::span<uint64_t>(bigInt.data(), bigInt.size()), d);
|
||||||
|
BEAST_EXPECT(result == TokenCodecErrc::success);
|
||||||
auto const foundMul = multiprecision_utils::toBoostMP(bigInt);
|
auto const foundMul = multiprecision_utils::toBoostMP(bigInt);
|
||||||
BEAST_EXPECT(refMul == foundMul);
|
BEAST_EXPECT(refMul == foundMul);
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < iters; ++i)
|
||||||
|
{
|
||||||
|
std::uint64_t const d = dist1(eng);
|
||||||
|
// Force overflow
|
||||||
|
std::vector<std::uint64_t> bigInt(
|
||||||
|
5, std::numeric_limits<std::uint64_t>::max());
|
||||||
|
auto const boostBigInt = multiprecision_utils::toBoostMP(
|
||||||
|
std::span<std::uint64_t>(bigInt.data(), bigInt.size()));
|
||||||
|
|
||||||
|
auto const refMul = boostBigInt * d;
|
||||||
|
|
||||||
|
auto const result = b58_fast::detail::inplace_bigint_mul(
|
||||||
|
std::span<uint64_t>(bigInt.data(), bigInt.size()), d);
|
||||||
|
BEAST_EXPECT(result == TokenCodecErrc::inputTooLarge);
|
||||||
|
auto const foundMul = multiprecision_utils::toBoostMP(bigInt);
|
||||||
|
BEAST_EXPECT(refMul != foundMul);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
|||||||
|
|
||||||
{ // invalid ledger (hash)
|
{ // invalid ledger (hash)
|
||||||
Json::Value params;
|
Json::Value params;
|
||||||
|
params[jss::account] = Account{"bob"}.human();
|
||||||
params[jss::ledger_hash] = 1;
|
params[jss::ledger_hash] = 1;
|
||||||
auto const result = env.rpc(
|
auto const result = env.rpc(
|
||||||
"json",
|
"json",
|
||||||
@@ -56,6 +57,50 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
|||||||
result[jss::error_message] == "Missing field 'account'.");
|
result[jss::error_message] == "Missing field 'account'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// test account non-string
|
||||||
|
auto testInvalidAccountParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::account] = param;
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json",
|
||||||
|
"account_currencies",
|
||||||
|
to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'account'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidAccountParam(1);
|
||||||
|
testInvalidAccountParam(1.1);
|
||||||
|
testInvalidAccountParam(true);
|
||||||
|
testInvalidAccountParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::arrayValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// test ident non-string
|
||||||
|
auto testInvalidIdentParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::ident] = param;
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json",
|
||||||
|
"account_currencies",
|
||||||
|
to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'ident'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidIdentParam(1);
|
||||||
|
testInvalidIdentParam(1.1);
|
||||||
|
testInvalidIdentParam(true);
|
||||||
|
testInvalidIdentParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidIdentParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidIdentParam(Json::Value(Json::arrayValue));
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Json::Value params;
|
Json::Value params;
|
||||||
params[jss::account] =
|
params[jss::account] =
|
||||||
@@ -198,6 +243,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(AccountCurrencies, app, ripple);
|
BEAST_DEFINE_TESTSUITE(AccountCurrencies, rpc, ripple);
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public:
|
|||||||
void
|
void
|
||||||
testErrors()
|
testErrors()
|
||||||
{
|
{
|
||||||
|
testcase("Errors");
|
||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
Env env(*this);
|
Env env(*this);
|
||||||
{
|
{
|
||||||
@@ -78,12 +79,53 @@ public:
|
|||||||
BEAST_EXPECT(
|
BEAST_EXPECT(
|
||||||
info[jss::result][jss::error_message] == "Account malformed.");
|
info[jss::result][jss::error_message] == "Account malformed.");
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
// Cannot pass a non-string into the `account` param
|
||||||
|
|
||||||
|
auto testInvalidAccountParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::account] = param;
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json", "account_info", to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'account'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidAccountParam(1);
|
||||||
|
testInvalidAccountParam(1.1);
|
||||||
|
testInvalidAccountParam(true);
|
||||||
|
testInvalidAccountParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::arrayValue));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Cannot pass a non-string into the `ident` param
|
||||||
|
|
||||||
|
auto testInvalidIdentParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::ident] = param;
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json", "account_info", to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'ident'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidIdentParam(1);
|
||||||
|
testInvalidIdentParam(1.1);
|
||||||
|
testInvalidIdentParam(true);
|
||||||
|
testInvalidIdentParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidIdentParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidIdentParam(Json::Value(Json::arrayValue));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the "signer_lists" argument in account_info.
|
// Test the "signer_lists" argument in account_info.
|
||||||
void
|
void
|
||||||
testSignerLists()
|
testSignerLists()
|
||||||
{
|
{
|
||||||
|
testcase("Signer lists");
|
||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
Env env(*this);
|
Env env(*this);
|
||||||
Account const alice{"alice"};
|
Account const alice{"alice"};
|
||||||
@@ -205,6 +247,7 @@ public:
|
|||||||
void
|
void
|
||||||
testSignerListsApiVersion2()
|
testSignerListsApiVersion2()
|
||||||
{
|
{
|
||||||
|
testcase("Signer lists APIv2");
|
||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
Env env{*this};
|
Env env{*this};
|
||||||
Account const alice{"alice"};
|
Account const alice{"alice"};
|
||||||
@@ -326,6 +369,7 @@ public:
|
|||||||
void
|
void
|
||||||
testSignerListsV2()
|
testSignerListsV2()
|
||||||
{
|
{
|
||||||
|
testcase("Signer lists v2");
|
||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
Env env(*this);
|
Env env(*this);
|
||||||
Account const alice{"alice"};
|
Account const alice{"alice"};
|
||||||
@@ -515,6 +559,7 @@ public:
|
|||||||
void
|
void
|
||||||
testAccountFlags(FeatureBitset const& features)
|
testAccountFlags(FeatureBitset const& features)
|
||||||
{
|
{
|
||||||
|
testcase("Account flags");
|
||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
|
|
||||||
Env env(*this, features);
|
Env env(*this, features);
|
||||||
@@ -652,7 +697,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(AccountInfo, app, ripple);
|
BEAST_DEFINE_TESTSUITE(AccountInfo, rpc, ripple);
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace ripple {
|
|||||||
|
|
||||||
namespace RPC {
|
namespace RPC {
|
||||||
|
|
||||||
class AccountLinesRPC_test : public beast::unit_test::suite
|
class AccountLines_test : public beast::unit_test::suite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void
|
void
|
||||||
@@ -55,6 +55,25 @@ public:
|
|||||||
lines[jss::result][jss::error_message] ==
|
lines[jss::result][jss::error_message] ==
|
||||||
RPC::make_error(rpcACT_MALFORMED)[jss::error_message]);
|
RPC::make_error(rpcACT_MALFORMED)[jss::error_message]);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
// test account non-string
|
||||||
|
auto testInvalidAccountParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::account] = param;
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json", "account_lines", to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'account'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidAccountParam(1);
|
||||||
|
testInvalidAccountParam(1.1);
|
||||||
|
testInvalidAccountParam(true);
|
||||||
|
testInvalidAccountParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::arrayValue));
|
||||||
|
}
|
||||||
Account const alice{"alice"};
|
Account const alice{"alice"};
|
||||||
{
|
{
|
||||||
// account_lines on an unfunded account.
|
// account_lines on an unfunded account.
|
||||||
@@ -1474,7 +1493,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(AccountLinesRPC, app, ripple);
|
BEAST_DEFINE_TESTSUITE(AccountLines, rpc, ripple);
|
||||||
|
|
||||||
} // namespace RPC
|
} // namespace RPC
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
@@ -125,8 +125,30 @@ public:
|
|||||||
|
|
||||||
// test error on no account
|
// test error on no account
|
||||||
{
|
{
|
||||||
auto resp = env.rpc("json", "account_objects");
|
Json::Value params;
|
||||||
BEAST_EXPECT(resp[jss::error_message] == "Syntax error.");
|
auto resp = env.rpc("json", "account_objects", to_string(params));
|
||||||
|
BEAST_EXPECT(
|
||||||
|
resp[jss::result][jss::error_message] ==
|
||||||
|
"Missing field 'account'.");
|
||||||
|
}
|
||||||
|
// test account non-string
|
||||||
|
{
|
||||||
|
auto testInvalidAccountParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::account] = param;
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json", "account_objects", to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'account'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidAccountParam(1);
|
||||||
|
testInvalidAccountParam(1.1);
|
||||||
|
testInvalidAccountParam(true);
|
||||||
|
testInvalidAccountParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::arrayValue));
|
||||||
}
|
}
|
||||||
// test error on malformed account string.
|
// test error on malformed account string.
|
||||||
{
|
{
|
||||||
@@ -1169,6 +1191,35 @@ public:
|
|||||||
"Invalid field \'marker\'."));
|
"Invalid field \'marker\'."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
testAccountNFTs()
|
||||||
|
{
|
||||||
|
testcase("account_nfts");
|
||||||
|
|
||||||
|
using namespace jtx;
|
||||||
|
Env env(*this);
|
||||||
|
|
||||||
|
// test validation
|
||||||
|
{
|
||||||
|
auto testInvalidAccountParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::account] = param;
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json", "account_nfts", to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'account'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidAccountParam(1);
|
||||||
|
testInvalidAccountParam(1.1);
|
||||||
|
testInvalidAccountParam(true);
|
||||||
|
testInvalidAccountParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::arrayValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
run() override
|
run() override
|
||||||
{
|
{
|
||||||
@@ -1177,10 +1228,11 @@ public:
|
|||||||
testUnsteppedThenSteppedWithNFTs();
|
testUnsteppedThenSteppedWithNFTs();
|
||||||
testObjectTypes();
|
testObjectTypes();
|
||||||
testNFTsMarker();
|
testNFTsMarker();
|
||||||
|
testAccountNFTs();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(AccountObjects, app, ripple);
|
BEAST_DEFINE_TESTSUITE(AccountObjects, rpc, ripple);
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ public:
|
|||||||
void
|
void
|
||||||
testNonAdminMinLimit()
|
testNonAdminMinLimit()
|
||||||
{
|
{
|
||||||
|
testcase("Non-Admin Min Limit");
|
||||||
|
|
||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
Env env{*this, envconfig(no_admin)};
|
Env env{*this, envconfig(no_admin)};
|
||||||
Account const gw("G1");
|
Account const gw("G1");
|
||||||
@@ -81,6 +83,9 @@ public:
|
|||||||
void
|
void
|
||||||
testSequential(bool asAdmin)
|
testSequential(bool asAdmin)
|
||||||
{
|
{
|
||||||
|
testcase(
|
||||||
|
std::string("Sequential - ") + (asAdmin ? "admin" : "non-admin"));
|
||||||
|
|
||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
Env env{*this, asAdmin ? envconfig() : envconfig(no_admin)};
|
Env env{*this, asAdmin ? envconfig() : envconfig(no_admin)};
|
||||||
Account const gw("G1");
|
Account const gw("G1");
|
||||||
@@ -215,6 +220,8 @@ public:
|
|||||||
void
|
void
|
||||||
testBadInput()
|
testBadInput()
|
||||||
{
|
{
|
||||||
|
testcase("Bad input");
|
||||||
|
|
||||||
using namespace jtx;
|
using namespace jtx;
|
||||||
Env env(*this);
|
Env env(*this);
|
||||||
Account const gw("G1");
|
Account const gw("G1");
|
||||||
@@ -233,6 +240,26 @@ public:
|
|||||||
BEAST_EXPECT(jrr[jss::error_message] == "Syntax error.");
|
BEAST_EXPECT(jrr[jss::error_message] == "Syntax error.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// test account non-string
|
||||||
|
auto testInvalidAccountParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::account] = param;
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json", "account_offers", to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'account'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidAccountParam(1);
|
||||||
|
testInvalidAccountParam(1.1);
|
||||||
|
testInvalidAccountParam(true);
|
||||||
|
testInvalidAccountParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::arrayValue));
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// empty string account
|
// empty string account
|
||||||
Json::Value jvParams;
|
Json::Value jvParams;
|
||||||
@@ -282,7 +309,9 @@ public:
|
|||||||
jvParams.toStyledString())[jss::result];
|
jvParams.toStyledString())[jss::result];
|
||||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
BEAST_EXPECT(jrr[jss::status] == "error");
|
BEAST_EXPECT(jrr[jss::status] == "error");
|
||||||
BEAST_EXPECT(jrr[jss::error_message] == "Invalid parameters.");
|
BEAST_EXPECTS(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'marker'.",
|
||||||
|
jrr.toStyledString());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -326,7 +355,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(AccountOffers, app, ripple);
|
BEAST_DEFINE_TESTSUITE(AccountOffers, rpc, ripple);
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ class AccountTx_test : public beast::unit_test::suite
|
|||||||
void
|
void
|
||||||
testParameters(unsigned int apiVersion)
|
testParameters(unsigned int apiVersion)
|
||||||
{
|
{
|
||||||
|
testcase("Parameters APIv" + std::to_string(apiVersion));
|
||||||
using namespace test::jtx;
|
using namespace test::jtx;
|
||||||
|
|
||||||
Env env(*this);
|
Env env(*this);
|
||||||
@@ -353,6 +354,25 @@ class AccountTx_test : public beast::unit_test::suite
|
|||||||
env.rpc("json", "account_tx", to_string(p)),
|
env.rpc("json", "account_tx", to_string(p)),
|
||||||
rpcLGR_IDX_MALFORMED));
|
rpcLGR_IDX_MALFORMED));
|
||||||
}
|
}
|
||||||
|
// test account non-string
|
||||||
|
{
|
||||||
|
auto testInvalidAccountParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::account] = param;
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json", "account_tx", to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'account'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidAccountParam(1);
|
||||||
|
testInvalidAccountParam(1.1);
|
||||||
|
testInvalidAccountParam(true);
|
||||||
|
testInvalidAccountParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::arrayValue));
|
||||||
|
}
|
||||||
// test binary and forward for bool/non bool values
|
// test binary and forward for bool/non bool values
|
||||||
{
|
{
|
||||||
Json::Value p{jParms};
|
Json::Value p{jParms};
|
||||||
@@ -388,6 +408,8 @@ class AccountTx_test : public beast::unit_test::suite
|
|||||||
void
|
void
|
||||||
testContents()
|
testContents()
|
||||||
{
|
{
|
||||||
|
testcase("Contents");
|
||||||
|
|
||||||
// Get results for all transaction types that can be associated
|
// Get results for all transaction types that can be associated
|
||||||
// with an account. Start by generating all transaction types.
|
// with an account. Start by generating all transaction types.
|
||||||
using namespace test::jtx;
|
using namespace test::jtx;
|
||||||
@@ -600,6 +622,8 @@ class AccountTx_test : public beast::unit_test::suite
|
|||||||
void
|
void
|
||||||
testAccountDelete()
|
testAccountDelete()
|
||||||
{
|
{
|
||||||
|
testcase("AccountDelete");
|
||||||
|
|
||||||
// Verify that if an account is resurrected then the account_tx RPC
|
// Verify that if an account is resurrected then the account_tx RPC
|
||||||
// command still recovers all transactions on that account before
|
// command still recovers all transactions on that account before
|
||||||
// and after resurrection.
|
// and after resurrection.
|
||||||
@@ -740,7 +764,7 @@ public:
|
|||||||
testAccountDelete();
|
testAccountDelete();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
BEAST_DEFINE_TESTSUITE(AccountTx, app, ripple);
|
BEAST_DEFINE_TESTSUITE(AccountTx, rpc, ripple);
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -64,6 +64,27 @@ class NoRippleCheck_test : public beast::unit_test::suite
|
|||||||
BEAST_EXPECT(result[jss::error_message] == "Missing field 'role'.");
|
BEAST_EXPECT(result[jss::error_message] == "Missing field 'role'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test account non-string
|
||||||
|
{
|
||||||
|
auto testInvalidAccountParam = [&](auto const& param) {
|
||||||
|
Json::Value params;
|
||||||
|
params[jss::account] = param;
|
||||||
|
params[jss::role] = "user";
|
||||||
|
auto jrr = env.rpc(
|
||||||
|
"json", "noripple_check", to_string(params))[jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jrr[jss::error_message] == "Invalid field 'account'.");
|
||||||
|
};
|
||||||
|
|
||||||
|
testInvalidAccountParam(1);
|
||||||
|
testInvalidAccountParam(1.1);
|
||||||
|
testInvalidAccountParam(true);
|
||||||
|
testInvalidAccountParam(Json::Value(Json::nullValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::objectValue));
|
||||||
|
testInvalidAccountParam(Json::Value(Json::arrayValue));
|
||||||
|
}
|
||||||
|
|
||||||
{ // invalid role field
|
{ // invalid role field
|
||||||
Json::Value params;
|
Json::Value params;
|
||||||
params[jss::account] = alice.human();
|
params[jss::account] = alice.human();
|
||||||
@@ -369,12 +390,12 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(NoRippleCheck, app, ripple);
|
BEAST_DEFINE_TESTSUITE(NoRippleCheck, rpc, ripple);
|
||||||
|
|
||||||
// These tests that deal with limit amounts are slow because of the
|
// These tests that deal with limit amounts are slow because of the
|
||||||
// offer/account setup, so making them manual -- the additional coverage
|
// offer/account setup, so making them manual -- the additional coverage
|
||||||
// provided by them is minimal
|
// provided by them is minimal
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(NoRippleCheckLimits, app, ripple, 1);
|
BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(NoRippleCheckLimits, rpc, ripple, 1);
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ doAccountChannels(RPC::JsonContext& context)
|
|||||||
if (!params.isMember(jss::account))
|
if (!params.isMember(jss::account))
|
||||||
return RPC::missing_field_error(jss::account);
|
return RPC::missing_field_error(jss::account);
|
||||||
|
|
||||||
|
if (!params[jss::account].isString())
|
||||||
|
return RPC::invalid_field_error(jss::account);
|
||||||
|
|
||||||
std::shared_ptr<ReadView const> ledger;
|
std::shared_ptr<ReadView const> ledger;
|
||||||
auto result = RPC::lookupLedger(ledger, context);
|
auto result = RPC::lookupLedger(ledger, context);
|
||||||
if (!ledger)
|
if (!ledger)
|
||||||
|
|||||||
@@ -33,19 +33,29 @@ doAccountCurrencies(RPC::JsonContext& context)
|
|||||||
{
|
{
|
||||||
auto& params = context.params;
|
auto& params = context.params;
|
||||||
|
|
||||||
|
if (!(params.isMember(jss::account) || params.isMember(jss::ident)))
|
||||||
|
return RPC::missing_field_error(jss::account);
|
||||||
|
|
||||||
|
std::string strIdent;
|
||||||
|
if (params.isMember(jss::account))
|
||||||
|
{
|
||||||
|
if (!params[jss::account].isString())
|
||||||
|
return RPC::invalid_field_error(jss::account);
|
||||||
|
strIdent = params[jss::account].asString();
|
||||||
|
}
|
||||||
|
else if (params.isMember(jss::ident))
|
||||||
|
{
|
||||||
|
if (!params[jss::ident].isString())
|
||||||
|
return RPC::invalid_field_error(jss::ident);
|
||||||
|
strIdent = params[jss::ident].asString();
|
||||||
|
}
|
||||||
|
|
||||||
// Get the current ledger
|
// Get the current ledger
|
||||||
std::shared_ptr<ReadView const> ledger;
|
std::shared_ptr<ReadView const> ledger;
|
||||||
auto result = RPC::lookupLedger(ledger, context);
|
auto result = RPC::lookupLedger(ledger, context);
|
||||||
if (!ledger)
|
if (!ledger)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (!(params.isMember(jss::account) || params.isMember(jss::ident)))
|
|
||||||
return RPC::missing_field_error(jss::account);
|
|
||||||
|
|
||||||
std::string const strIdent(
|
|
||||||
params.isMember(jss::account) ? params[jss::account].asString()
|
|
||||||
: params[jss::ident].asString());
|
|
||||||
|
|
||||||
// Get info on account.
|
// Get info on account.
|
||||||
auto id = parseBase58<AccountID>(strIdent);
|
auto id = parseBase58<AccountID>(strIdent);
|
||||||
if (!id)
|
if (!id)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <xrpl/json/json_value.h>
|
#include <xrpl/json/json_value.h>
|
||||||
#include <xrpl/protocol/ErrorCodes.h>
|
#include <xrpl/protocol/ErrorCodes.h>
|
||||||
#include <xrpl/protocol/Indexes.h>
|
#include <xrpl/protocol/Indexes.h>
|
||||||
|
#include <xrpl/protocol/RPCErr.h>
|
||||||
#include <xrpl/protocol/UintTypes.h>
|
#include <xrpl/protocol/UintTypes.h>
|
||||||
#include <xrpl/protocol/jss.h>
|
#include <xrpl/protocol/jss.h>
|
||||||
#include <grpc/status.h>
|
#include <grpc/status.h>
|
||||||
@@ -53,9 +54,17 @@ doAccountInfo(RPC::JsonContext& context)
|
|||||||
|
|
||||||
std::string strIdent;
|
std::string strIdent;
|
||||||
if (params.isMember(jss::account))
|
if (params.isMember(jss::account))
|
||||||
|
{
|
||||||
|
if (!params[jss::account].isString())
|
||||||
|
return RPC::invalid_field_error(jss::account);
|
||||||
strIdent = params[jss::account].asString();
|
strIdent = params[jss::account].asString();
|
||||||
|
}
|
||||||
else if (params.isMember(jss::ident))
|
else if (params.isMember(jss::ident))
|
||||||
|
{
|
||||||
|
if (!params[jss::ident].isString())
|
||||||
|
return RPC::invalid_field_error(jss::ident);
|
||||||
strIdent = params[jss::ident].asString();
|
strIdent = params[jss::ident].asString();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return RPC::missing_field_error(jss::account);
|
return RPC::missing_field_error(jss::account);
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ doAccountLines(RPC::JsonContext& context)
|
|||||||
if (!params.isMember(jss::account))
|
if (!params.isMember(jss::account))
|
||||||
return RPC::missing_field_error(jss::account);
|
return RPC::missing_field_error(jss::account);
|
||||||
|
|
||||||
|
if (!params[jss::account].isString())
|
||||||
|
return RPC::invalid_field_error(jss::account);
|
||||||
|
|
||||||
std::shared_ptr<ReadView const> ledger;
|
std::shared_ptr<ReadView const> ledger;
|
||||||
auto result = RPC::lookupLedger(ledger, context);
|
auto result = RPC::lookupLedger(ledger, context);
|
||||||
if (!ledger)
|
if (!ledger)
|
||||||
|
|||||||
@@ -54,17 +54,19 @@ doAccountNFTs(RPC::JsonContext& context)
|
|||||||
if (!params.isMember(jss::account))
|
if (!params.isMember(jss::account))
|
||||||
return RPC::missing_field_error(jss::account);
|
return RPC::missing_field_error(jss::account);
|
||||||
|
|
||||||
std::shared_ptr<ReadView const> ledger;
|
if (!params[jss::account].isString())
|
||||||
auto result = RPC::lookupLedger(ledger, context);
|
return RPC::invalid_field_error(jss::account);
|
||||||
if (ledger == nullptr)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
auto id = parseBase58<AccountID>(params[jss::account].asString());
|
auto id = parseBase58<AccountID>(params[jss::account].asString());
|
||||||
if (!id)
|
if (!id)
|
||||||
{
|
{
|
||||||
RPC::inject_error(rpcACT_MALFORMED, result);
|
return rpcError(rpcACT_MALFORMED);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ReadView const> ledger;
|
||||||
|
auto result = RPC::lookupLedger(ledger, context);
|
||||||
|
if (ledger == nullptr)
|
||||||
|
return result;
|
||||||
auto const accountID{id.value()};
|
auto const accountID{id.value()};
|
||||||
|
|
||||||
if (!ledger->exists(keylet::account(accountID)))
|
if (!ledger->exists(keylet::account(accountID)))
|
||||||
@@ -183,6 +185,9 @@ doAccountObjects(RPC::JsonContext& context)
|
|||||||
if (!params.isMember(jss::account))
|
if (!params.isMember(jss::account))
|
||||||
return RPC::missing_field_error(jss::account);
|
return RPC::missing_field_error(jss::account);
|
||||||
|
|
||||||
|
if (!params[jss::account].isString())
|
||||||
|
return RPC::invalid_field_error(jss::account);
|
||||||
|
|
||||||
std::shared_ptr<ReadView const> ledger;
|
std::shared_ptr<ReadView const> ledger;
|
||||||
auto result = RPC::lookupLedger(ledger, context);
|
auto result = RPC::lookupLedger(ledger, context);
|
||||||
if (ledger == nullptr)
|
if (ledger == nullptr)
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ doAccountOffers(RPC::JsonContext& context)
|
|||||||
if (!params.isMember(jss::account))
|
if (!params.isMember(jss::account))
|
||||||
return RPC::missing_field_error(jss::account);
|
return RPC::missing_field_error(jss::account);
|
||||||
|
|
||||||
|
if (!params[jss::account].isString())
|
||||||
|
return RPC::invalid_field_error(jss::account);
|
||||||
|
|
||||||
std::shared_ptr<ReadView const> ledger;
|
std::shared_ptr<ReadView const> ledger;
|
||||||
auto result = RPC::lookupLedger(ledger, context);
|
auto result = RPC::lookupLedger(ledger, context);
|
||||||
if (!ledger)
|
if (!ledger)
|
||||||
@@ -84,7 +87,7 @@ doAccountOffers(RPC::JsonContext& context)
|
|||||||
return *err;
|
return *err;
|
||||||
|
|
||||||
if (limit == 0)
|
if (limit == 0)
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
return RPC::invalid_field_error(jss::limit);
|
||||||
|
|
||||||
Json::Value& jsonOffers(result[jss::offers] = Json::arrayValue);
|
Json::Value& jsonOffers(result[jss::offers] = Json::arrayValue);
|
||||||
std::vector<std::shared_ptr<SLE const>> offers;
|
std::vector<std::shared_ptr<SLE const>> offers;
|
||||||
@@ -101,13 +104,13 @@ doAccountOffers(RPC::JsonContext& context)
|
|||||||
std::stringstream marker(params[jss::marker].asString());
|
std::stringstream marker(params[jss::marker].asString());
|
||||||
std::string value;
|
std::string value;
|
||||||
if (!std::getline(marker, value, ','))
|
if (!std::getline(marker, value, ','))
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
return RPC::invalid_field_error(jss::marker);
|
||||||
|
|
||||||
if (!startAfter.parseHex(value))
|
if (!startAfter.parseHex(value))
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
return RPC::invalid_field_error(jss::marker);
|
||||||
|
|
||||||
if (!std::getline(marker, value, ','))
|
if (!std::getline(marker, value, ','))
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
return RPC::invalid_field_error(jss::marker);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -115,7 +118,7 @@ doAccountOffers(RPC::JsonContext& context)
|
|||||||
}
|
}
|
||||||
catch (boost::bad_lexical_cast&)
|
catch (boost::bad_lexical_cast&)
|
||||||
{
|
{
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
return RPC::invalid_field_error(jss::marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We then must check if the object pointed to by the marker is actually
|
// We then must check if the object pointed to by the marker is actually
|
||||||
|
|||||||
@@ -426,12 +426,12 @@ doAccountTxJson(RPC::JsonContext& context)
|
|||||||
if (context.apiVersion > 1u && params.isMember(jss::binary) &&
|
if (context.apiVersion > 1u && params.isMember(jss::binary) &&
|
||||||
!params[jss::binary].isBool())
|
!params[jss::binary].isBool())
|
||||||
{
|
{
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
return RPC::invalid_field_error(jss::binary);
|
||||||
}
|
}
|
||||||
if (context.apiVersion > 1u && params.isMember(jss::forward) &&
|
if (context.apiVersion > 1u && params.isMember(jss::forward) &&
|
||||||
!params[jss::forward].isBool())
|
!params[jss::forward].isBool())
|
||||||
{
|
{
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
return RPC::invalid_field_error(jss::forward);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.limit = params.isMember(jss::limit) ? params[jss::limit].asUInt() : 0;
|
args.limit = params.isMember(jss::limit) ? params[jss::limit].asUInt() : 0;
|
||||||
@@ -440,7 +440,10 @@ doAccountTxJson(RPC::JsonContext& context)
|
|||||||
params.isMember(jss::forward) && params[jss::forward].asBool();
|
params.isMember(jss::forward) && params[jss::forward].asBool();
|
||||||
|
|
||||||
if (!params.isMember(jss::account))
|
if (!params.isMember(jss::account))
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
return RPC::missing_field_error(jss::account);
|
||||||
|
|
||||||
|
if (!params[jss::account].isString())
|
||||||
|
return RPC::invalid_field_error(jss::account);
|
||||||
|
|
||||||
auto const account =
|
auto const account =
|
||||||
parseBase58<AccountID>(params[jss::account].asString());
|
parseBase58<AccountID>(params[jss::account].asString());
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ doNoRippleCheck(RPC::JsonContext& context)
|
|||||||
|
|
||||||
if (!params.isMember("role"))
|
if (!params.isMember("role"))
|
||||||
return RPC::missing_field_error("role");
|
return RPC::missing_field_error("role");
|
||||||
|
|
||||||
|
if (!params[jss::account].isString())
|
||||||
|
return RPC::invalid_field_error(jss::account);
|
||||||
|
|
||||||
bool roleGateway = false;
|
bool roleGateway = false;
|
||||||
{
|
{
|
||||||
std::string const role = params["role"].asString();
|
std::string const role = params["role"].asString();
|
||||||
@@ -90,7 +94,7 @@ doNoRippleCheck(RPC::JsonContext& context)
|
|||||||
if (context.apiVersion > 1u && params.isMember(jss::transactions) &&
|
if (context.apiVersion > 1u && params.isMember(jss::transactions) &&
|
||||||
!params[jss::transactions].isBool())
|
!params[jss::transactions].isBool())
|
||||||
{
|
{
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
return RPC::invalid_field_error(jss::transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ReadView const> ledger;
|
std::shared_ptr<ReadView const> ledger;
|
||||||
|
|||||||
Reference in New Issue
Block a user