mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Merge branch 'develop' into ximinez/lending-refactoring-3
This commit is contained in:
6
.github/scripts/levelization/README.md
vendored
6
.github/scripts/levelization/README.md
vendored
@@ -72,15 +72,15 @@ It generates many files of [results](results):
|
|||||||
desired as described above. In a perfect repo, this file will be
|
desired as described above. In a perfect repo, this file will be
|
||||||
empty.
|
empty.
|
||||||
This file is committed to the repo, and is used by the [levelization
|
This file is committed to the repo, and is used by the [levelization
|
||||||
Github workflow](../../workflows/check-levelization.yml) to validate
|
Github workflow](../../workflows/reusable-check-levelization.yml) to validate
|
||||||
that nothing changed.
|
that nothing changed.
|
||||||
- [`ordering.txt`](results/ordering.txt): A list showing relationships
|
- [`ordering.txt`](results/ordering.txt): A list showing relationships
|
||||||
between modules where there are no loops as they actually exist, as
|
between modules where there are no loops as they actually exist, as
|
||||||
opposed to how they are desired as described above.
|
opposed to how they are desired as described above.
|
||||||
This file is committed to the repo, and is used by the [levelization
|
This file is committed to the repo, and is used by the [levelization
|
||||||
Github workflow](../../workflows/check-levelization.yml) to validate
|
Github workflow](../../workflows/reusable-check-levelization.yml) to validate
|
||||||
that nothing changed.
|
that nothing changed.
|
||||||
- [`levelization.yml`](../../workflows/check-levelization.yml)
|
- [`levelization.yml`](../../workflows/reusable-check-levelization.yml)
|
||||||
Github Actions workflow to test that levelization loops haven't
|
Github Actions workflow to test that levelization loops haven't
|
||||||
changed. Unfortunately, if changes are detected, it can't tell if
|
changed. Unfortunately, if changes are detected, it can't tell if
|
||||||
they are improvements or not, so if you have resolved any issues or
|
they are improvements or not, so if you have resolved any issues or
|
||||||
|
|||||||
12
.github/workflows/on-pr.yml
vendored
12
.github/workflows/on-pr.yml
vendored
@@ -50,8 +50,8 @@ jobs:
|
|||||||
files: |
|
files: |
|
||||||
# These paths are unique to `on-pr.yml`.
|
# These paths are unique to `on-pr.yml`.
|
||||||
.github/scripts/levelization/**
|
.github/scripts/levelization/**
|
||||||
.github/workflows/check-levelization.yml
|
.github/workflows/reusable-check-levelization.yml
|
||||||
.github/workflows/notify-clio.yml
|
.github/workflows/reusable-notify-clio.yml
|
||||||
.github/workflows/on-pr.yml
|
.github/workflows/on-pr.yml
|
||||||
|
|
||||||
# Keep the paths below in sync with those in `on-trigger.yml`.
|
# Keep the paths below in sync with those in `on-trigger.yml`.
|
||||||
@@ -59,7 +59,7 @@ jobs:
|
|||||||
.github/actions/build-test/**
|
.github/actions/build-test/**
|
||||||
.github/actions/setup-conan/**
|
.github/actions/setup-conan/**
|
||||||
.github/scripts/strategy-matrix/**
|
.github/scripts/strategy-matrix/**
|
||||||
.github/workflows/build-test.yml
|
.github/workflows/reusable-build-test.yml
|
||||||
.github/workflows/reusable-strategy-matrix.yml
|
.github/workflows/reusable-strategy-matrix.yml
|
||||||
.codecov.yml
|
.codecov.yml
|
||||||
cmake/**
|
cmake/**
|
||||||
@@ -93,12 +93,12 @@ jobs:
|
|||||||
check-levelization:
|
check-levelization:
|
||||||
needs: should-run
|
needs: should-run
|
||||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||||
uses: ./.github/workflows/check-levelization.yml
|
uses: ./.github/workflows/reusable-check-levelization.yml
|
||||||
|
|
||||||
build-test:
|
build-test:
|
||||||
needs: should-run
|
needs: should-run
|
||||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||||
uses: ./.github/workflows/build-test.yml
|
uses: ./.github/workflows/reusable-build-test.yml
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [linux, macos, windows]
|
os: [linux, macos, windows]
|
||||||
@@ -112,7 +112,7 @@ jobs:
|
|||||||
- should-run
|
- should-run
|
||||||
- build-test
|
- build-test
|
||||||
if: ${{ needs.should-run.outputs.go == 'true' && contains(fromJSON('["release", "master"]'), github.ref_name) }}
|
if: ${{ needs.should-run.outputs.go == 'true' && contains(fromJSON('["release", "master"]'), github.ref_name) }}
|
||||||
uses: ./.github/workflows/notify-clio.yml
|
uses: ./.github/workflows/reusable-notify-clio.yml
|
||||||
secrets:
|
secrets:
|
||||||
clio_notify_token: ${{ secrets.CLIO_NOTIFY_TOKEN }}
|
clio_notify_token: ${{ secrets.CLIO_NOTIFY_TOKEN }}
|
||||||
conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||||
|
|||||||
8
.github/workflows/on-trigger.yml
vendored
8
.github/workflows/on-trigger.yml
vendored
@@ -14,7 +14,7 @@ on:
|
|||||||
- master
|
- master
|
||||||
paths:
|
paths:
|
||||||
# These paths are unique to `on-trigger.yml`.
|
# These paths are unique to `on-trigger.yml`.
|
||||||
- ".github/workflows/check-missing-commits.yml"
|
- ".github/workflows/reusable-check-missing-commits.yml"
|
||||||
- ".github/workflows/on-trigger.yml"
|
- ".github/workflows/on-trigger.yml"
|
||||||
- ".github/workflows/publish-docs.yml"
|
- ".github/workflows/publish-docs.yml"
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ on:
|
|||||||
- ".github/actions/build-test/**"
|
- ".github/actions/build-test/**"
|
||||||
- ".github/actions/setup-conan/**"
|
- ".github/actions/setup-conan/**"
|
||||||
- ".github/scripts/strategy-matrix/**"
|
- ".github/scripts/strategy-matrix/**"
|
||||||
- ".github/workflows/build-test.yml"
|
- ".github/workflows/reusable-build-test.yml"
|
||||||
- ".github/workflows/reusable-strategy-matrix.yml"
|
- ".github/workflows/reusable-strategy-matrix.yml"
|
||||||
- ".codecov.yml"
|
- ".codecov.yml"
|
||||||
- "cmake/**"
|
- "cmake/**"
|
||||||
@@ -71,10 +71,10 @@ defaults:
|
|||||||
jobs:
|
jobs:
|
||||||
check-missing-commits:
|
check-missing-commits:
|
||||||
if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && contains(fromJSON('["develop", "release"]'), github.ref_name) }}
|
if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && contains(fromJSON('["develop", "release"]'), github.ref_name) }}
|
||||||
uses: ./.github/workflows/check-missing-commits.yml
|
uses: ./.github/workflows/reusable-check-missing-commits.yml
|
||||||
|
|
||||||
build-test:
|
build-test:
|
||||||
uses: ./.github/workflows/build-test.yml
|
uses: ./.github/workflows/reusable-build-test.yml
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [linux, macos, windows]
|
os: [linux, macos, windows]
|
||||||
|
|||||||
@@ -72,8 +72,10 @@ class STCurrency;
|
|||||||
STYPE(STI_VL, 7) \
|
STYPE(STI_VL, 7) \
|
||||||
STYPE(STI_ACCOUNT, 8) \
|
STYPE(STI_ACCOUNT, 8) \
|
||||||
STYPE(STI_NUMBER, 9) \
|
STYPE(STI_NUMBER, 9) \
|
||||||
|
STYPE(STI_INT32, 10) \
|
||||||
|
STYPE(STI_INT64, 11) \
|
||||||
\
|
\
|
||||||
/* 10-13 are reserved */ \
|
/* 12-13 are reserved */ \
|
||||||
STYPE(STI_OBJECT, 14) \
|
STYPE(STI_OBJECT, 14) \
|
||||||
STYPE(STI_ARRAY, 15) \
|
STYPE(STI_ARRAY, 15) \
|
||||||
\
|
\
|
||||||
@@ -356,6 +358,9 @@ using SF_UINT256 = TypedField<STBitString<256>>;
|
|||||||
using SF_UINT384 = TypedField<STBitString<384>>;
|
using SF_UINT384 = TypedField<STBitString<384>>;
|
||||||
using SF_UINT512 = TypedField<STBitString<512>>;
|
using SF_UINT512 = TypedField<STBitString<512>>;
|
||||||
|
|
||||||
|
using SF_INT32 = TypedField<STInteger<std::int32_t>>;
|
||||||
|
using SF_INT64 = TypedField<STInteger<std::int64_t>>;
|
||||||
|
|
||||||
using SF_ACCOUNT = TypedField<STAccount>;
|
using SF_ACCOUNT = TypedField<STAccount>;
|
||||||
using SF_AMOUNT = TypedField<STAmount>;
|
using SF_AMOUNT = TypedField<STAmount>;
|
||||||
using SF_ISSUE = TypedField<STIssue>;
|
using SF_ISSUE = TypedField<STIssue>;
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ using STUInt16 = STInteger<std::uint16_t>;
|
|||||||
using STUInt32 = STInteger<std::uint32_t>;
|
using STUInt32 = STInteger<std::uint32_t>;
|
||||||
using STUInt64 = STInteger<std::uint64_t>;
|
using STUInt64 = STInteger<std::uint64_t>;
|
||||||
|
|
||||||
|
using STInt32 = STInteger<std::int32_t>;
|
||||||
|
|
||||||
template <typename Integer>
|
template <typename Integer>
|
||||||
inline STInteger<Integer>::STInteger(Integer v) : value_(v)
|
inline STInteger<Integer>::STInteger(Integer v) : value_(v)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -231,6 +231,8 @@ public:
|
|||||||
getFieldH192(SField const& field) const;
|
getFieldH192(SField const& field) const;
|
||||||
uint256
|
uint256
|
||||||
getFieldH256(SField const& field) const;
|
getFieldH256(SField const& field) const;
|
||||||
|
std::int32_t
|
||||||
|
getFieldI32(SField const& field) const;
|
||||||
AccountID
|
AccountID
|
||||||
getAccountID(SField const& field) const;
|
getAccountID(SField const& field) const;
|
||||||
|
|
||||||
@@ -365,6 +367,8 @@ public:
|
|||||||
void
|
void
|
||||||
setFieldH256(SField const& field, uint256 const&);
|
setFieldH256(SField const& field, uint256 const&);
|
||||||
void
|
void
|
||||||
|
setFieldI32(SField const& field, std::int32_t);
|
||||||
|
void
|
||||||
setFieldVL(SField const& field, Blob const&);
|
setFieldVL(SField const& field, Blob const&);
|
||||||
void
|
void
|
||||||
setFieldVL(SField const& field, Slice const&);
|
setFieldVL(SField const& field, Slice const&);
|
||||||
|
|||||||
@@ -208,6 +208,12 @@ TYPED_SFIELD(sfAssetsMaximum, NUMBER, 3)
|
|||||||
TYPED_SFIELD(sfAssetsTotal, NUMBER, 4)
|
TYPED_SFIELD(sfAssetsTotal, NUMBER, 4)
|
||||||
TYPED_SFIELD(sfLossUnrealized, NUMBER, 5)
|
TYPED_SFIELD(sfLossUnrealized, NUMBER, 5)
|
||||||
|
|
||||||
|
// int32
|
||||||
|
// NOTE: Do not use `sfDummyInt32`. It's so far the only use of INT32
|
||||||
|
// in this file and has been defined here for test only.
|
||||||
|
// TODO: Replace `sfDummyInt32` with actually useful field.
|
||||||
|
TYPED_SFIELD(sfDummyInt32, INT32, 1) // for tests only
|
||||||
|
|
||||||
// currency amount (common)
|
// currency amount (common)
|
||||||
TYPED_SFIELD(sfAmount, AMOUNT, 1)
|
TYPED_SFIELD(sfAmount, AMOUNT, 1)
|
||||||
TYPED_SFIELD(sfBalance, AMOUNT, 2)
|
TYPED_SFIELD(sfBalance, AMOUNT, 2)
|
||||||
|
|||||||
@@ -249,4 +249,33 @@ STUInt64::getJson(JsonOptions) const
|
|||||||
return convertToString(value_, 16); // Convert to base 16
|
return convertToString(value_, 16); // Convert to base 16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <>
|
||||||
|
STInteger<std::int32_t>::STInteger(SerialIter& sit, SField const& name)
|
||||||
|
: STInteger(name, sit.get32())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
SerializedTypeID
|
||||||
|
STInt32::getSType() const
|
||||||
|
{
|
||||||
|
return STI_INT32;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string
|
||||||
|
STInt32::getText() const
|
||||||
|
{
|
||||||
|
return std::to_string(value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
Json::Value
|
||||||
|
STInt32::getJson(JsonOptions) const
|
||||||
|
{
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -647,6 +647,12 @@ STObject::getFieldH256(SField const& field) const
|
|||||||
return getFieldByValue<STUInt256>(field);
|
return getFieldByValue<STUInt256>(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::int32_t
|
||||||
|
STObject::getFieldI32(SField const& field) const
|
||||||
|
{
|
||||||
|
return getFieldByValue<STInt32>(field);
|
||||||
|
}
|
||||||
|
|
||||||
AccountID
|
AccountID
|
||||||
STObject::getAccountID(SField const& field) const
|
STObject::getAccountID(SField const& field) const
|
||||||
{
|
{
|
||||||
@@ -761,6 +767,12 @@ STObject::setFieldH256(SField const& field, uint256 const& v)
|
|||||||
setFieldUsingSetValue<STUInt256>(field, v);
|
setFieldUsingSetValue<STUInt256>(field, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STObject::setFieldI32(SField const& field, std::int32_t v)
|
||||||
|
{
|
||||||
|
setFieldUsingSetValue<STInt32>(field, v);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
STObject::setFieldV256(SField const& field, STVector256 const& v)
|
STObject::setFieldV256(SField const& field, STVector256 const& v)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -563,30 +563,6 @@ parseLeaf(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case STI_UINT192: {
|
|
||||||
if (!value.isString())
|
|
||||||
{
|
|
||||||
error = bad_type(json_name, fieldName);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint192 num;
|
|
||||||
|
|
||||||
if (auto const s = value.asString(); !num.parseHex(s))
|
|
||||||
{
|
|
||||||
if (!s.empty())
|
|
||||||
{
|
|
||||||
error = invalid_data(json_name, fieldName);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
num.zero();
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = detail::make_stvar<STUInt192>(field, num);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case STI_UINT160: {
|
case STI_UINT160: {
|
||||||
if (!value.isString())
|
if (!value.isString())
|
||||||
{
|
{
|
||||||
@@ -611,6 +587,30 @@ parseLeaf(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case STI_UINT192: {
|
||||||
|
if (!value.isString())
|
||||||
|
{
|
||||||
|
error = bad_type(json_name, fieldName);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint192 num;
|
||||||
|
|
||||||
|
if (auto const s = value.asString(); !num.parseHex(s))
|
||||||
|
{
|
||||||
|
if (!s.empty())
|
||||||
|
{
|
||||||
|
error = invalid_data(json_name, fieldName);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
num.zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = detail::make_stvar<STUInt192>(field, num);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case STI_UINT256: {
|
case STI_UINT256: {
|
||||||
if (!value.isString())
|
if (!value.isString())
|
||||||
{
|
{
|
||||||
@@ -635,6 +635,52 @@ parseLeaf(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case STI_INT32:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (value.isString())
|
||||||
|
{
|
||||||
|
ret = detail::make_stvar<STInt32>(
|
||||||
|
field,
|
||||||
|
beast::lexicalCastThrow<std::int32_t>(
|
||||||
|
value.asString()));
|
||||||
|
}
|
||||||
|
else if (value.isInt())
|
||||||
|
{
|
||||||
|
// future-proofing - a static assert failure if the JSON
|
||||||
|
// library ever supports larger ints
|
||||||
|
// In such case, we will need additional bounds checks here
|
||||||
|
static_assert(
|
||||||
|
std::is_same_v<decltype(value.asInt()), std::int32_t>);
|
||||||
|
ret = detail::make_stvar<STInt32>(field, value.asInt());
|
||||||
|
}
|
||||||
|
else if (value.isUInt())
|
||||||
|
{
|
||||||
|
auto const uintValue = value.asUInt();
|
||||||
|
if (uintValue >
|
||||||
|
static_cast<std::uint32_t>(
|
||||||
|
std::numeric_limits<std::int32_t>::max()))
|
||||||
|
{
|
||||||
|
error = out_of_range(json_name, fieldName);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = detail::make_stvar<STInt32>(
|
||||||
|
field, static_cast<std::int32_t>(uintValue));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error = bad_type(json_name, fieldName);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception const&)
|
||||||
|
{
|
||||||
|
error = invalid_data(json_name, fieldName);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case STI_VL:
|
case STI_VL:
|
||||||
if (!value.isString())
|
if (!value.isString())
|
||||||
{
|
{
|
||||||
@@ -1120,8 +1166,7 @@ parseArray(
|
|||||||
Json::Value const objectFields(json[i][objectName]);
|
Json::Value const objectFields(json[i][objectName]);
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << json_name << "."
|
ss << json_name << "." << "[" << i << "]." << objectName;
|
||||||
<< "[" << i << "]." << objectName;
|
|
||||||
|
|
||||||
auto ret = parseObject(
|
auto ret = parseObject(
|
||||||
ss.str(), objectFields, nameField, depth + 1, error);
|
ss.str(), objectFields, nameField, depth + 1, error);
|
||||||
|
|||||||
@@ -208,6 +208,9 @@ STVar::constructST(SerializedTypeID id, int depth, Args&&... args)
|
|||||||
case STI_UINT256:
|
case STI_UINT256:
|
||||||
construct<STUInt256>(std::forward<Args>(args)...);
|
construct<STUInt256>(std::forward<Args>(args)...);
|
||||||
return;
|
return;
|
||||||
|
case STI_INT32:
|
||||||
|
construct<STInt32>(std::forward<Args>(args)...);
|
||||||
|
return;
|
||||||
case STI_VECTOR256:
|
case STI_VECTOR256:
|
||||||
construct<STVector256>(std::forward<Args>(args)...);
|
construct<STVector256>(std::forward<Args>(args)...);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -83,6 +83,12 @@ Serializer::addInteger(std::uint64_t i)
|
|||||||
{
|
{
|
||||||
return add64(i);
|
return add64(i);
|
||||||
}
|
}
|
||||||
|
template <>
|
||||||
|
int
|
||||||
|
Serializer::addInteger(std::int32_t i)
|
||||||
|
{
|
||||||
|
return add32(i);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Serializer::addRaw(Blob const& vector)
|
Serializer::addRaw(Blob const& vector)
|
||||||
|
|||||||
@@ -122,10 +122,27 @@ struct STAccount_test : public beast::unit_test::suite
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
testAccountID()
|
||||||
|
{
|
||||||
|
auto const s = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
|
||||||
|
if (auto const parsed = parseBase58<AccountID>(s); BEAST_EXPECT(parsed))
|
||||||
|
{
|
||||||
|
BEAST_EXPECT(toBase58(*parsed) == s);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto const s =
|
||||||
|
"âabcd1rNxp4h8apvRis6mJf9Sh8C6iRxfrDWNâabcdAVâ\xc2\x80\xc2\x8f";
|
||||||
|
BEAST_EXPECT(!parseBase58<AccountID>(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
run() override
|
run() override
|
||||||
{
|
{
|
||||||
testSTAccount();
|
testSTAccount();
|
||||||
|
testAccountID();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ struct STInteger_test : public beast::unit_test::suite
|
|||||||
void
|
void
|
||||||
testUInt8()
|
testUInt8()
|
||||||
{
|
{
|
||||||
|
testcase("UInt8");
|
||||||
STUInt8 u8(255);
|
STUInt8 u8(255);
|
||||||
BEAST_EXPECT(u8.value() == 255);
|
BEAST_EXPECT(u8.value() == 255);
|
||||||
BEAST_EXPECT(u8.getText() == "255");
|
BEAST_EXPECT(u8.getText() == "255");
|
||||||
@@ -56,6 +57,7 @@ struct STInteger_test : public beast::unit_test::suite
|
|||||||
void
|
void
|
||||||
testUInt16()
|
testUInt16()
|
||||||
{
|
{
|
||||||
|
testcase("UInt16");
|
||||||
STUInt16 u16(65535);
|
STUInt16 u16(65535);
|
||||||
BEAST_EXPECT(u16.value() == 65535);
|
BEAST_EXPECT(u16.value() == 65535);
|
||||||
BEAST_EXPECT(u16.getText() == "65535");
|
BEAST_EXPECT(u16.getText() == "65535");
|
||||||
@@ -80,6 +82,7 @@ struct STInteger_test : public beast::unit_test::suite
|
|||||||
void
|
void
|
||||||
testUInt32()
|
testUInt32()
|
||||||
{
|
{
|
||||||
|
testcase("UInt32");
|
||||||
STUInt32 u32(4'294'967'295u);
|
STUInt32 u32(4'294'967'295u);
|
||||||
BEAST_EXPECT(u32.value() == 4'294'967'295u);
|
BEAST_EXPECT(u32.value() == 4'294'967'295u);
|
||||||
BEAST_EXPECT(u32.getText() == "4294967295");
|
BEAST_EXPECT(u32.getText() == "4294967295");
|
||||||
@@ -102,6 +105,7 @@ struct STInteger_test : public beast::unit_test::suite
|
|||||||
void
|
void
|
||||||
testUInt64()
|
testUInt64()
|
||||||
{
|
{
|
||||||
|
testcase("UInt64");
|
||||||
STUInt64 u64(0xFFFFFFFFFFFFFFFFull);
|
STUInt64 u64(0xFFFFFFFFFFFFFFFFull);
|
||||||
BEAST_EXPECT(u64.value() == 0xFFFFFFFFFFFFFFFFull);
|
BEAST_EXPECT(u64.value() == 0xFFFFFFFFFFFFFFFFull);
|
||||||
BEAST_EXPECT(u64.getText() == "18446744073709551615");
|
BEAST_EXPECT(u64.getText() == "18446744073709551615");
|
||||||
@@ -120,6 +124,29 @@ struct STInteger_test : public beast::unit_test::suite
|
|||||||
u64_2.getJson(JsonOptions::none) == "18446744073709551615");
|
u64_2.getJson(JsonOptions::none) == "18446744073709551615");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
testInt32()
|
||||||
|
{
|
||||||
|
testcase("Int32");
|
||||||
|
{
|
||||||
|
int const minInt32 = -2147483648;
|
||||||
|
STInt32 i32(minInt32);
|
||||||
|
BEAST_EXPECT(i32.value() == minInt32);
|
||||||
|
BEAST_EXPECT(i32.getText() == "-2147483648");
|
||||||
|
BEAST_EXPECT(i32.getSType() == STI_INT32);
|
||||||
|
BEAST_EXPECT(i32.getJson(JsonOptions::none) == minInt32);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int const maxInt32 = 2147483647;
|
||||||
|
STInt32 i32(maxInt32);
|
||||||
|
BEAST_EXPECT(i32.value() == maxInt32);
|
||||||
|
BEAST_EXPECT(i32.getText() == "2147483647");
|
||||||
|
BEAST_EXPECT(i32.getSType() == STI_INT32);
|
||||||
|
BEAST_EXPECT(i32.getJson(JsonOptions::none) == maxInt32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
run() override
|
run() override
|
||||||
{
|
{
|
||||||
@@ -127,6 +154,7 @@ struct STInteger_test : public beast::unit_test::suite
|
|||||||
testUInt16();
|
testUInt16();
|
||||||
testUInt32();
|
testUInt32();
|
||||||
testUInt64();
|
testUInt64();
|
||||||
|
testInt32();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -736,6 +736,107 @@ class STParsedJSON_test : public beast::unit_test::suite
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
testInt32()
|
||||||
|
{
|
||||||
|
testcase("Int32");
|
||||||
|
{
|
||||||
|
Json::Value j;
|
||||||
|
int const minInt32 = -2147483648;
|
||||||
|
j[sfDummyInt32] = minInt32;
|
||||||
|
STParsedJSONObject obj("Test", j);
|
||||||
|
BEAST_EXPECT(obj.object.has_value());
|
||||||
|
if (BEAST_EXPECT(obj.object->isFieldPresent(sfDummyInt32)))
|
||||||
|
BEAST_EXPECT(obj.object->getFieldI32(sfDummyInt32) == minInt32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// max value
|
||||||
|
{
|
||||||
|
Json::Value j;
|
||||||
|
int const maxInt32 = 2147483647;
|
||||||
|
j[sfDummyInt32] = maxInt32;
|
||||||
|
STParsedJSONObject obj("Test", j);
|
||||||
|
BEAST_EXPECT(obj.object.has_value());
|
||||||
|
if (BEAST_EXPECT(obj.object->isFieldPresent(sfDummyInt32)))
|
||||||
|
BEAST_EXPECT(obj.object->getFieldI32(sfDummyInt32) == maxInt32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// max uint value
|
||||||
|
{
|
||||||
|
Json::Value j;
|
||||||
|
unsigned int const maxUInt32 = 2147483647u;
|
||||||
|
j[sfDummyInt32] = maxUInt32;
|
||||||
|
STParsedJSONObject obj("Test", j);
|
||||||
|
BEAST_EXPECT(obj.object.has_value());
|
||||||
|
if (BEAST_EXPECT(obj.object->isFieldPresent(sfDummyInt32)))
|
||||||
|
BEAST_EXPECT(
|
||||||
|
obj.object->getFieldI32(sfDummyInt32) ==
|
||||||
|
static_cast<int32_t>(maxUInt32));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with string value
|
||||||
|
{
|
||||||
|
Json::Value j;
|
||||||
|
j[sfDummyInt32] = "2147483647";
|
||||||
|
STParsedJSONObject obj("Test", j);
|
||||||
|
BEAST_EXPECT(obj.object.has_value());
|
||||||
|
if (BEAST_EXPECT(obj.object->isFieldPresent(sfDummyInt32)))
|
||||||
|
BEAST_EXPECT(
|
||||||
|
obj.object->getFieldI32(sfDummyInt32) == 2147483647u);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with string negative value
|
||||||
|
{
|
||||||
|
Json::Value j;
|
||||||
|
int value = -2147483648;
|
||||||
|
j[sfDummyInt32] = std::to_string(value);
|
||||||
|
STParsedJSONObject obj("Test", j);
|
||||||
|
BEAST_EXPECT(obj.object.has_value());
|
||||||
|
if (BEAST_EXPECT(obj.object->isFieldPresent(sfDummyInt32)))
|
||||||
|
BEAST_EXPECT(obj.object->getFieldI32(sfDummyInt32) == value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test out of range value for int32 (negative)
|
||||||
|
{
|
||||||
|
Json::Value j;
|
||||||
|
j[sfDummyInt32] = "-2147483649";
|
||||||
|
STParsedJSONObject obj("Test", j);
|
||||||
|
BEAST_EXPECT(!obj.object.has_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test out of range value for int32 (positive)
|
||||||
|
{
|
||||||
|
Json::Value j;
|
||||||
|
j[sfDummyInt32] = 2147483648u;
|
||||||
|
STParsedJSONObject obj("Test", j);
|
||||||
|
BEAST_EXPECT(!obj.object.has_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test string value out of range
|
||||||
|
{
|
||||||
|
Json::Value j;
|
||||||
|
j[sfDummyInt32] = "2147483648";
|
||||||
|
STParsedJSONObject obj("Test", j);
|
||||||
|
BEAST_EXPECT(!obj.object.has_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test bad_type (arrayValue)
|
||||||
|
{
|
||||||
|
Json::Value j;
|
||||||
|
j[sfDummyInt32] = Json::Value(Json::arrayValue);
|
||||||
|
STParsedJSONObject obj("Test", j);
|
||||||
|
BEAST_EXPECT(!obj.object.has_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test bad_type (objectValue)
|
||||||
|
{
|
||||||
|
Json::Value j;
|
||||||
|
j[sfDummyInt32] = Json::Value(Json::objectValue);
|
||||||
|
STParsedJSONObject obj("Test", j);
|
||||||
|
BEAST_EXPECT(!obj.object.has_value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
testBlob()
|
testBlob()
|
||||||
{
|
{
|
||||||
@@ -1338,8 +1439,7 @@ class STParsedJSON_test : public beast::unit_test::suite
|
|||||||
issueJson["issuer"] = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
|
issueJson["issuer"] = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
|
||||||
j[sfAsset] = issueJson;
|
j[sfAsset] = issueJson;
|
||||||
STParsedJSONObject obj("Test", j);
|
STParsedJSONObject obj("Test", j);
|
||||||
if (BEAST_EXPECTS(
|
if (BEAST_EXPECT(obj.object.has_value()))
|
||||||
obj.object.has_value(), obj.error.toStyledString()))
|
|
||||||
{
|
{
|
||||||
BEAST_EXPECT(obj.object->isFieldPresent(sfAsset));
|
BEAST_EXPECT(obj.object->isFieldPresent(sfAsset));
|
||||||
auto const& issueField = (*obj.object)[sfAsset];
|
auto const& issueField = (*obj.object)[sfAsset];
|
||||||
@@ -2235,6 +2335,7 @@ class STParsedJSON_test : public beast::unit_test::suite
|
|||||||
testUInt160();
|
testUInt160();
|
||||||
testUInt192();
|
testUInt192();
|
||||||
testUInt256();
|
testUInt256();
|
||||||
|
testInt32();
|
||||||
testBlob();
|
testBlob();
|
||||||
testVector256();
|
testVector256();
|
||||||
testAccount();
|
testAccount();
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of rippled: https://github.com/ripple/rippled
|
|
||||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#include <xrpl/beast/unit_test.h>
|
|
||||||
#include <xrpl/protocol/UintTypes.h>
|
|
||||||
|
|
||||||
namespace ripple {
|
|
||||||
|
|
||||||
struct types_test : public beast::unit_test::suite
|
|
||||||
{
|
|
||||||
void
|
|
||||||
testAccountID()
|
|
||||||
{
|
|
||||||
auto const s = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
|
|
||||||
if (auto const parsed = parseBase58<AccountID>(s); BEAST_EXPECT(parsed))
|
|
||||||
{
|
|
||||||
BEAST_EXPECT(toBase58(*parsed) == s);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto const s =
|
|
||||||
"âabcd1rNxp4h8apvRis6mJf9Sh8C6iRxfrDWNâabcdAVâ\xc2\x80\xc2\x8f";
|
|
||||||
BEAST_EXPECT(!parseBase58<AccountID>(s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
run() override
|
|
||||||
{
|
|
||||||
testAccountID();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(types, protocol, ripple);
|
|
||||||
|
|
||||||
} // namespace ripple
|
|
||||||
Reference in New Issue
Block a user