mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 19:25:51 +00:00
Merge branch 'ripple/wamr' into ripple/wamr-host-functions
This commit is contained in:
@@ -72,8 +72,10 @@ class STCurrency;
|
||||
STYPE(STI_VL, 7) \
|
||||
STYPE(STI_ACCOUNT, 8) \
|
||||
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_ARRAY, 15) \
|
||||
\
|
||||
@@ -356,6 +358,9 @@ using SF_UINT256 = TypedField<STBitString<256>>;
|
||||
using SF_UINT384 = TypedField<STBitString<384>>;
|
||||
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_AMOUNT = TypedField<STAmount>;
|
||||
using SF_ISSUE = TypedField<STIssue>;
|
||||
|
||||
@@ -81,6 +81,8 @@ using STUInt16 = STInteger<std::uint16_t>;
|
||||
using STUInt32 = STInteger<std::uint32_t>;
|
||||
using STUInt64 = STInteger<std::uint64_t>;
|
||||
|
||||
using STInt32 = STInteger<std::int32_t>;
|
||||
|
||||
template <typename Integer>
|
||||
inline STInteger<Integer>::STInteger(Integer v) : value_(v)
|
||||
{
|
||||
|
||||
@@ -231,6 +231,8 @@ public:
|
||||
getFieldH192(SField const& field) const;
|
||||
uint256
|
||||
getFieldH256(SField const& field) const;
|
||||
std::int32_t
|
||||
getFieldI32(SField const& field) const;
|
||||
AccountID
|
||||
getAccountID(SField const& field) const;
|
||||
|
||||
@@ -365,6 +367,8 @@ public:
|
||||
void
|
||||
setFieldH256(SField const& field, uint256 const&);
|
||||
void
|
||||
setFieldI32(SField const& field, std::int32_t);
|
||||
void
|
||||
setFieldVL(SField const& field, Blob const&);
|
||||
void
|
||||
setFieldVL(SField const& field, Slice const&);
|
||||
|
||||
@@ -208,6 +208,12 @@ TYPED_SFIELD(sfAssetsMaximum, NUMBER, 3)
|
||||
TYPED_SFIELD(sfAssetsTotal, NUMBER, 4)
|
||||
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)
|
||||
TYPED_SFIELD(sfAmount, AMOUNT, 1)
|
||||
TYPED_SFIELD(sfBalance, AMOUNT, 2)
|
||||
|
||||
@@ -249,4 +249,33 @@ STUInt64::getJson(JsonOptions) const
|
||||
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
|
||||
|
||||
@@ -647,6 +647,12 @@ STObject::getFieldH256(SField const& field) const
|
||||
return getFieldByValue<STUInt256>(field);
|
||||
}
|
||||
|
||||
std::int32_t
|
||||
STObject::getFieldI32(SField const& field) const
|
||||
{
|
||||
return getFieldByValue<STInt32>(field);
|
||||
}
|
||||
|
||||
AccountID
|
||||
STObject::getAccountID(SField const& field) const
|
||||
{
|
||||
@@ -761,6 +767,12 @@ STObject::setFieldH256(SField const& field, uint256 const& v)
|
||||
setFieldUsingSetValue<STUInt256>(field, v);
|
||||
}
|
||||
|
||||
void
|
||||
STObject::setFieldI32(SField const& field, std::int32_t v)
|
||||
{
|
||||
setFieldUsingSetValue<STInt32>(field, v);
|
||||
}
|
||||
|
||||
void
|
||||
STObject::setFieldV256(SField const& field, STVector256 const& v)
|
||||
{
|
||||
|
||||
@@ -563,30 +563,6 @@ parseLeaf(
|
||||
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: {
|
||||
if (!value.isString())
|
||||
{
|
||||
@@ -611,6 +587,30 @@ parseLeaf(
|
||||
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: {
|
||||
if (!value.isString())
|
||||
{
|
||||
@@ -635,6 +635,52 @@ parseLeaf(
|
||||
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:
|
||||
if (!value.isString())
|
||||
{
|
||||
@@ -1120,8 +1166,7 @@ parseArray(
|
||||
Json::Value const objectFields(json[i][objectName]);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << json_name << "."
|
||||
<< "[" << i << "]." << objectName;
|
||||
ss << json_name << "." << "[" << i << "]." << objectName;
|
||||
|
||||
auto ret = parseObject(
|
||||
ss.str(), objectFields, nameField, depth + 1, error);
|
||||
|
||||
@@ -208,6 +208,9 @@ STVar::constructST(SerializedTypeID id, int depth, Args&&... args)
|
||||
case STI_UINT256:
|
||||
construct<STUInt256>(std::forward<Args>(args)...);
|
||||
return;
|
||||
case STI_INT32:
|
||||
construct<STInt32>(std::forward<Args>(args)...);
|
||||
return;
|
||||
case STI_VECTOR256:
|
||||
construct<STVector256>(std::forward<Args>(args)...);
|
||||
return;
|
||||
|
||||
@@ -83,6 +83,12 @@ Serializer::addInteger(std::uint64_t i)
|
||||
{
|
||||
return add64(i);
|
||||
}
|
||||
template <>
|
||||
int
|
||||
Serializer::addInteger(std::int32_t i)
|
||||
{
|
||||
return add32(i);
|
||||
}
|
||||
|
||||
int
|
||||
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
|
||||
run() override
|
||||
{
|
||||
testSTAccount();
|
||||
testAccountID();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ struct STInteger_test : public beast::unit_test::suite
|
||||
void
|
||||
testUInt8()
|
||||
{
|
||||
testcase("UInt8");
|
||||
STUInt8 u8(255);
|
||||
BEAST_EXPECT(u8.value() == 255);
|
||||
BEAST_EXPECT(u8.getText() == "255");
|
||||
@@ -56,6 +57,7 @@ struct STInteger_test : public beast::unit_test::suite
|
||||
void
|
||||
testUInt16()
|
||||
{
|
||||
testcase("UInt16");
|
||||
STUInt16 u16(65535);
|
||||
BEAST_EXPECT(u16.value() == 65535);
|
||||
BEAST_EXPECT(u16.getText() == "65535");
|
||||
@@ -80,6 +82,7 @@ struct STInteger_test : public beast::unit_test::suite
|
||||
void
|
||||
testUInt32()
|
||||
{
|
||||
testcase("UInt32");
|
||||
STUInt32 u32(4'294'967'295u);
|
||||
BEAST_EXPECT(u32.value() == 4'294'967'295u);
|
||||
BEAST_EXPECT(u32.getText() == "4294967295");
|
||||
@@ -102,6 +105,7 @@ struct STInteger_test : public beast::unit_test::suite
|
||||
void
|
||||
testUInt64()
|
||||
{
|
||||
testcase("UInt64");
|
||||
STUInt64 u64(0xFFFFFFFFFFFFFFFFull);
|
||||
BEAST_EXPECT(u64.value() == 0xFFFFFFFFFFFFFFFFull);
|
||||
BEAST_EXPECT(u64.getText() == "18446744073709551615");
|
||||
@@ -120,6 +124,29 @@ struct STInteger_test : public beast::unit_test::suite
|
||||
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
|
||||
run() override
|
||||
{
|
||||
@@ -127,6 +154,7 @@ struct STInteger_test : public beast::unit_test::suite
|
||||
testUInt16();
|
||||
testUInt32();
|
||||
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
|
||||
testBlob()
|
||||
{
|
||||
@@ -1338,8 +1439,7 @@ class STParsedJSON_test : public beast::unit_test::suite
|
||||
issueJson["issuer"] = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
|
||||
j[sfAsset] = issueJson;
|
||||
STParsedJSONObject obj("Test", j);
|
||||
if (BEAST_EXPECTS(
|
||||
obj.object.has_value(), obj.error.toStyledString()))
|
||||
if (BEAST_EXPECT(obj.object.has_value()))
|
||||
{
|
||||
BEAST_EXPECT(obj.object->isFieldPresent(sfAsset));
|
||||
auto const& issueField = (*obj.object)[sfAsset];
|
||||
@@ -2235,6 +2335,7 @@ class STParsedJSON_test : public beast::unit_test::suite
|
||||
testUInt160();
|
||||
testUInt192();
|
||||
testUInt256();
|
||||
testInt32();
|
||||
testBlob();
|
||||
testVector256();
|
||||
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