mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-22 23:00:55 +00:00
Add Vector256 support to the locator (#6131)
* add Vector256 nesting/length support * [WIP] add tests * fix tests * simplify with helper function * oops typo * remove static variable * respond to comments * STBaseOrUInt256->FieldValue * oops * add more tests for coverage * respond to comments
This commit is contained in:
@@ -29,6 +29,12 @@ toBytes(std::uint32_t value)
|
||||
return Bytes{b, e};
|
||||
}
|
||||
|
||||
static Bytes
|
||||
toBytes(uint256 const& value)
|
||||
{
|
||||
return Bytes{value.begin(), value.end()};
|
||||
}
|
||||
|
||||
static Bytes
|
||||
toBytes(Asset const& asset)
|
||||
{
|
||||
@@ -303,6 +309,11 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
testcase("getTxField");
|
||||
using namespace test::jtx;
|
||||
|
||||
std::string const credIdHex =
|
||||
"0011223344556677889900112233445566778899001122334455667788990011";
|
||||
uint256 credId;
|
||||
BEAST_EXPECT(credId.parseHex(credIdHex));
|
||||
|
||||
Env env{*this};
|
||||
OpenView ov{*env.current()};
|
||||
STTx const stx = STTx(ttESCROW_FINISH, [&](auto& obj) {
|
||||
@@ -310,6 +321,9 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
obj.setAccountID(sfOwner, env.master.id());
|
||||
obj.setFieldU32(sfOfferSequence, env.seq(env.master));
|
||||
obj.setFieldArray(sfMemos, STArray{});
|
||||
STVector256 credIds;
|
||||
credIds.push_back(credId);
|
||||
obj.setFieldV256(sfCredentialIDs, credIds);
|
||||
});
|
||||
ApplyContext ac = createApplyContext(env, ov, stx);
|
||||
auto const dummyEscrow =
|
||||
@@ -340,6 +354,12 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(
|
||||
memos.error() == HostFunctionError::NOT_LEAF_FIELD);
|
||||
|
||||
auto const credentialIds = hfs.getTxField(sfCredentialIDs);
|
||||
if (BEAST_EXPECT(!credentialIds.has_value()))
|
||||
BEAST_EXPECTS(
|
||||
credentialIds.error() == HostFunctionError::NOT_LEAF_FIELD,
|
||||
std::to_string(HfErrorToInt(credentialIds.error())));
|
||||
|
||||
auto const nonField = hfs.getTxField(sfInvalid);
|
||||
if (BEAST_EXPECT(!nonField.has_value()))
|
||||
BEAST_EXPECT(
|
||||
@@ -450,6 +470,15 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(*amountField == toBytes(XRP(100)));
|
||||
}
|
||||
|
||||
// Should return the PreviousTxnID field from the escrow ledger object
|
||||
auto const previousTxnId =
|
||||
hfs.getCurrentLedgerObjField(sfPreviousTxnID);
|
||||
if (BEAST_EXPECT(previousTxnId.has_value()))
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
*previousTxnId == toBytes(env.tx()->getTransactionID()));
|
||||
}
|
||||
|
||||
// Should return nullopt for a field not present
|
||||
auto const notPresent = hfs.getCurrentLedgerObjField(sfOwner);
|
||||
BEAST_EXPECT(
|
||||
@@ -541,6 +570,11 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
Env env{*this};
|
||||
OpenView ov{*env.current()};
|
||||
|
||||
std::string const credIdHex =
|
||||
"0011223344556677889900112233445566778899001122334455667788990011";
|
||||
uint256 credId;
|
||||
BEAST_EXPECT(credId.parseHex(credIdHex));
|
||||
|
||||
// Create a transaction with a nested array field
|
||||
STTx const stx = STTx(ttESCROW_FINISH, [&](auto& obj) {
|
||||
obj.setAccountID(sfAccount, env.master.id());
|
||||
@@ -549,6 +583,9 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
memoObj.setFieldVL(sfMemoData, Slice("hello", 5));
|
||||
memos.push_back(memoObj);
|
||||
obj.setFieldArray(sfMemos, memos);
|
||||
STVector256 credIds;
|
||||
credIds.push_back(credId);
|
||||
obj.setFieldV256(sfCredentialIDs, credIds);
|
||||
});
|
||||
|
||||
ApplyContext ac = createApplyContext(env, ov, stx);
|
||||
@@ -578,6 +615,24 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Locator for sfCredentialIDs[0]
|
||||
std::vector<int32_t> locatorVec = {sfCredentialIDs.fieldCode, 0};
|
||||
Slice locator(
|
||||
reinterpret_cast<uint8_t const*>(locatorVec.data()),
|
||||
locatorVec.size() * sizeof(int32_t));
|
||||
|
||||
auto const result = hfs.getTxNestedField(locator);
|
||||
if (BEAST_EXPECTS(
|
||||
result.has_value(),
|
||||
std::to_string(static_cast<int>(result.error()))))
|
||||
{
|
||||
std::string credIdResult(
|
||||
result.value().begin(), result.value().end());
|
||||
BEAST_EXPECT(strHex(credIdResult) == credIdHex);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// can use the nested locator for base fields too
|
||||
std::vector<int32_t> locatorVec = {sfAccount.fieldCode};
|
||||
@@ -637,6 +692,11 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
sfMemoData.fieldCode},
|
||||
HostFunctionError::INDEX_OUT_OF_BOUNDS);
|
||||
|
||||
// Locator for non-existent index
|
||||
expectError(
|
||||
{sfCredentialIDs.fieldCode, 1}, // index 1 does not exist
|
||||
HostFunctionError::INDEX_OUT_OF_BOUNDS);
|
||||
|
||||
// Locator for non-existent nested field
|
||||
expectError(
|
||||
{sfMemos.fieldCode,
|
||||
@@ -661,6 +721,10 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
// Locator for STArray
|
||||
expectError({sfMemos.fieldCode}, HostFunctionError::NOT_LEAF_FIELD);
|
||||
|
||||
// Locator for STVector256
|
||||
expectError(
|
||||
{sfCredentialIDs.fieldCode}, HostFunctionError::NOT_LEAF_FIELD);
|
||||
|
||||
// Locator for nesting into non-array/object field
|
||||
expectError(
|
||||
{sfAccount.fieldCode, // sfAccount is not an array or object
|
||||
@@ -956,6 +1020,11 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
testcase("getTxArrayLen");
|
||||
using namespace test::jtx;
|
||||
|
||||
std::string const credIdHex =
|
||||
"0011223344556677889900112233445566778899001122334455667788990011";
|
||||
uint256 credId;
|
||||
BEAST_EXPECT(credId.parseHex(credIdHex));
|
||||
|
||||
Env env{*this};
|
||||
OpenView ov{*env.current()};
|
||||
|
||||
@@ -974,6 +1043,9 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
memos.push_back(memoObj);
|
||||
}
|
||||
obj.setFieldArray(sfMemos, memos);
|
||||
STVector256 credIds;
|
||||
credIds.push_back(credId);
|
||||
obj.setFieldV256(sfCredentialIDs, credIds);
|
||||
});
|
||||
|
||||
ApplyContext ac = createApplyContext(env, ov, stx);
|
||||
@@ -996,6 +1068,11 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
if (BEAST_EXPECT(!missingArray.has_value()))
|
||||
BEAST_EXPECT(
|
||||
missingArray.error() == HostFunctionError::FIELD_NOT_FOUND);
|
||||
|
||||
// Should return 1 for sfCredentialIDs
|
||||
auto const credIdsLen = hfs.getTxArrayLen(sfCredentialIDs);
|
||||
if (BEAST_EXPECT(credIdsLen.has_value()))
|
||||
BEAST_EXPECT(credIdsLen.value() == 1);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2195,9 +2272,9 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
// clang-format on
|
||||
|
||||
void
|
||||
testFloatTrace()
|
||||
testTraceFloat()
|
||||
{
|
||||
testcase("FloatTrace");
|
||||
testcase("traceFloat");
|
||||
using namespace test::jtx;
|
||||
|
||||
{
|
||||
@@ -2251,7 +2328,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
void
|
||||
testFloatFromInt()
|
||||
{
|
||||
testcase("FloatFromInt");
|
||||
testcase("floatFromInt");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
@@ -2298,7 +2375,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
void
|
||||
testFloatFromUint()
|
||||
{
|
||||
testcase("FloatFromUint");
|
||||
testcase("floatFromUint");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
@@ -2339,7 +2416,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
void
|
||||
testFloatSet()
|
||||
{
|
||||
testcase("FloatSet");
|
||||
testcase("floatSet");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
@@ -2426,7 +2503,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
void
|
||||
testFloatCompare()
|
||||
{
|
||||
testcase("FloatCompare");
|
||||
testcase("floatCompare");
|
||||
using namespace test::jtx;
|
||||
|
||||
Env env{*this};
|
||||
@@ -3071,7 +3148,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
void
|
||||
testFloats()
|
||||
{
|
||||
testFloatTrace();
|
||||
testTraceFloat();
|
||||
testFloatFromInt();
|
||||
testFloatFromUint();
|
||||
testFloatSet();
|
||||
|
||||
Reference in New Issue
Block a user