mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-19 05:10:55 +00:00
feat: Porting wasm host function tests to new design
This commit is contained in:
@@ -821,4 +821,24 @@ mod tests {
|
||||
"one {MAX_FIELD_BYTES}-byte value against a {TRANSFER_LIMIT_BYTES}-byte budget"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_u32_arg_success() {
|
||||
let number: u32 = 0x12345678;
|
||||
let le_array: [u8; 4] = number.to_le_bytes();
|
||||
assert_eq!(le_array, [0x78, 0x56, 0x34, 0x12]);
|
||||
|
||||
let result = read_u32_arg(&le_array);
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(result.unwrap(), number.try_into().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_u32_arg_invalid_length() {
|
||||
let le_array = [0x56, 0x34, 0x12];
|
||||
|
||||
let result = read_u32_arg(&le_array);
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err(), HostError::InvalidParams);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/HashRouter.h>
|
||||
#include <xrpl/core/NetworkIDService.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/ledger/AmendmentTable.h>
|
||||
#include <xrpl/ledger/PendingSaves.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/STValidation.h>
|
||||
#include <xrpl/server/LoadFeeTrack.h>
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
@@ -15,11 +24,15 @@
|
||||
#include <helpers/TestFamily.h>
|
||||
#include <helpers/TestSink.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
@@ -40,6 +53,107 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Minimal AmendmentTable for tests.
|
||||
*
|
||||
* The real table is built by `makeAmendmentTable`, which lives in the app (xrpld) tier and
|
||||
* so cannot link into a libxrpl-tier test binary. But the wasm host only ever calls
|
||||
* `find(name)` — a name -> amendment-id resolve — and whether an amendment is *enabled* is
|
||||
* read from the ledger's `Rules`, never from here. So `find` delegates to the feature
|
||||
* registry (the same source `makeAmendmentTable` would seed from) and every other method,
|
||||
* unused by these tests, throws if reached.
|
||||
*/
|
||||
class TestAmendmentTable final : public AmendmentTable
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] uint256
|
||||
find(std::string const& name) const override
|
||||
{
|
||||
return getRegisteredFeature(name).value_or(uint256{});
|
||||
}
|
||||
|
||||
bool
|
||||
veto(uint256 const&) override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::veto not implemented");
|
||||
}
|
||||
bool
|
||||
unVeto(uint256 const&) override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::unVeto not implemented");
|
||||
}
|
||||
bool
|
||||
enable(uint256 const&) override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::enable not implemented");
|
||||
}
|
||||
[[nodiscard]] bool
|
||||
isEnabled(uint256 const&) const override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::isEnabled not implemented");
|
||||
}
|
||||
[[nodiscard]] bool
|
||||
isSupported(uint256 const&) const override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::isSupported not implemented");
|
||||
}
|
||||
[[nodiscard]] bool
|
||||
hasUnsupportedEnabled() const override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::hasUnsupportedEnabled not implemented");
|
||||
}
|
||||
[[nodiscard]] std::optional<NetClock::time_point>
|
||||
firstUnsupportedExpected() const override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::firstUnsupportedExpected not implemented");
|
||||
}
|
||||
[[nodiscard]] json::Value
|
||||
getJson(bool) const override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::getJson not implemented");
|
||||
}
|
||||
[[nodiscard]] json::Value
|
||||
getJson(uint256 const&, bool) const override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::getJson(amendment) not implemented");
|
||||
}
|
||||
[[nodiscard]] bool
|
||||
needValidatedLedger(LedgerIndex) const override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::needValidatedLedger not implemented");
|
||||
}
|
||||
void
|
||||
doValidatedLedger(LedgerIndex, std::set<uint256> const&, majorityAmendments_t const&) override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::doValidatedLedger not implemented");
|
||||
}
|
||||
void
|
||||
trustChanged(hash_set<PublicKey> const&) override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::trustChanged not implemented");
|
||||
}
|
||||
std::map<uint256, std::uint32_t>
|
||||
doVoting(
|
||||
Rules const&,
|
||||
NetClock::time_point,
|
||||
std::set<uint256> const&,
|
||||
majorityAmendments_t const&,
|
||||
std::vector<std::shared_ptr<STValidation>> const&) override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::doVoting not implemented");
|
||||
}
|
||||
[[nodiscard]] std::vector<uint256>
|
||||
doValidation(std::set<uint256> const&) const override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::doValidation not implemented");
|
||||
}
|
||||
[[nodiscard]] std::vector<uint256>
|
||||
getDesired() const override
|
||||
{
|
||||
throw std::logic_error("TestAmendmentTable::getDesired not implemented");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple NetworkIDService implementation for tests.
|
||||
*/
|
||||
@@ -91,6 +205,7 @@ class TestServiceRegistry : public ServiceRegistry
|
||||
logs_.journal("TaggedCache")};
|
||||
PendingSaves pendingSaves_;
|
||||
std::optional<uint256> trapTxID_;
|
||||
TestAmendmentTable amendmentTable_;
|
||||
|
||||
public:
|
||||
TestServiceRegistry() = default;
|
||||
@@ -140,10 +255,13 @@ public:
|
||||
}
|
||||
|
||||
// Protocol and validation services
|
||||
// See `TestAmendmentTable`: the wasm host only resolves a name -> id here; enabled
|
||||
// state is read from the ledger's `Rules`. The real factory (`makeAmendmentTable`) is
|
||||
// app-tier and won't link into a libxrpl test binary, so a stub table is used.
|
||||
AmendmentTable&
|
||||
getAmendmentTable() override
|
||||
{
|
||||
throw std::logic_error("TestServiceRegistry::getAmendmentTable() not implemented");
|
||||
return amendmentTable_;
|
||||
}
|
||||
|
||||
HashRouter&
|
||||
|
||||
150
src/tests/libxrpl/tx/wasm/RealHostFixture.h
Normal file
150
src/tests/libxrpl/tx/wasm/RealHostFixture.h
Normal file
@@ -0,0 +1,150 @@
|
||||
#pragma once
|
||||
|
||||
// Base for the "impl" wasm tests: a *real* `WasmHostFunctionsImpl` over a *real* ledger,
|
||||
// built with no Application / jtx / beast::unit_test::Suite. The ledger is a `TxTest`
|
||||
// (genesis ledger + OpenView + real transactor dispatch); the host is constructed from
|
||||
// its `ServiceRegistry` and `OpenView` through an `ApplyContext`.
|
||||
//
|
||||
// This is the counterpart to `HostContextFixture` (mock host, interop): here the host
|
||||
// really computes, so a test asserts a value against the ledger's own source of truth
|
||||
// (`keylet::escrow`, a real field's bytes, `wasm_float`), rather than what a mock was
|
||||
// asked. Pure-computation host functions (keylets, floats, check_sig, sha512_half, nft
|
||||
// decoders) ignore the ledger; the reading getters read the object `leKey` points at.
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/ledger/ApplyView.h> // TapNone
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Fees.h>
|
||||
#include <xrpl/protocol/Indexes.h> // keylet::account
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STNumber.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/wasm/HostFuncImpl.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/TxTest.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
static Bytes
|
||||
toBytes(std::uint8_t value)
|
||||
{
|
||||
return {value};
|
||||
}
|
||||
|
||||
static Bytes
|
||||
toBytes(std::uint16_t value)
|
||||
{
|
||||
auto const* b = reinterpret_cast<uint8_t const*>(&value);
|
||||
auto const* e = reinterpret_cast<uint8_t const*>(&value + 1);
|
||||
return Bytes{b, e};
|
||||
}
|
||||
|
||||
static Bytes
|
||||
toBytes(std::uint32_t value)
|
||||
{
|
||||
auto const* b = reinterpret_cast<uint8_t const*>(&value);
|
||||
auto const* e = reinterpret_cast<uint8_t const*>(&value + 1);
|
||||
return Bytes{b, e};
|
||||
}
|
||||
|
||||
static Bytes
|
||||
toBytes(uint256 const& value)
|
||||
{
|
||||
return Bytes{value.begin(), value.end()};
|
||||
}
|
||||
|
||||
static Bytes
|
||||
toBytes(Issue const& issue)
|
||||
{
|
||||
Serializer s;
|
||||
s.addBitString(issue.currency);
|
||||
if (!isXRP(issue.currency))
|
||||
s.addBitString(issue.account);
|
||||
auto const data = s.getData();
|
||||
return data;
|
||||
}
|
||||
|
||||
static Bytes
|
||||
toBytes(Asset const& asset)
|
||||
{
|
||||
if (asset.holds<Issue>())
|
||||
return toBytes(asset.get<Issue>());
|
||||
|
||||
auto const& mptIssue = asset.get<MPTIssue>();
|
||||
auto const& mptID = mptIssue.getMptID();
|
||||
return Bytes{mptID.cbegin(), mptID.cend()};
|
||||
}
|
||||
|
||||
static Bytes
|
||||
toBytes(STAmount const& amount)
|
||||
{
|
||||
Serializer msg;
|
||||
amount.add(msg);
|
||||
auto const data = msg.getData();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static Bytes
|
||||
toBytes(STNumber const& number)
|
||||
{
|
||||
Serializer msg;
|
||||
number.add(msg);
|
||||
auto const data = msg.getData();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
class WasmImplTest : public testing::Test
|
||||
{
|
||||
public:
|
||||
// The real ledger. Tests populate it with `ledger.createAccount()` / `submit()` /
|
||||
// `close()` before reading through the host.
|
||||
TxTest ledger;
|
||||
|
||||
// A real host bound to `leKey` — the "current"/home object the `*_field` and
|
||||
// `*_arr_len` getters read. Defaults to a throwaway keylet for the many functions
|
||||
// (keylets, floats, sig, hash, nft decoders) that never touch the current object.
|
||||
//
|
||||
// Returns a reference into a fixture-owned host so its `ApplyContext&` outlives it;
|
||||
// call once per test.
|
||||
WasmHostFunctionsImpl&
|
||||
host(Keylet const& leKey = keylet::account(AccountID{}))
|
||||
{
|
||||
// The finish tx the host runs under. Its contents are irrelevant to the
|
||||
// functions these tests exercise; it only has to be a well-formed shell.
|
||||
finishTx_ = std::make_shared<STTx>(ttESCROW_FINISH, [](STObject&) {});
|
||||
context_.emplace(
|
||||
ledger.getServiceRegistry(),
|
||||
ledger.getOpenLedger(),
|
||||
*finishTx_,
|
||||
tesSUCCESS,
|
||||
ledger.getOpenLedger().fees().base,
|
||||
TapNone,
|
||||
beast::Journal{beast::Journal::getNullSink()});
|
||||
host_.emplace(*context_, leKey);
|
||||
return *host_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<STTx const> finishTx_;
|
||||
std::optional<ApplyContext> context_;
|
||||
std::optional<WasmHostFunctionsImpl> host_;
|
||||
};
|
||||
|
||||
} // namespace xrpl::test
|
||||
39
src/tests/libxrpl/tx/wasm/host_functions/AccountKeylet.cpp
Normal file
39
src/tests/libxrpl/tx/wasm/host_functions/AccountKeylet.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct AccountKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(AccountKeyletImpl, MatchesAccountKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::account(owner.id());
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().accountKeylet(owner);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(AccountKeyletImpl, UnsetAccountIsInvalidAccount)
|
||||
{
|
||||
auto const result = host().accountKeylet(AccountID{});
|
||||
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
53
src/tests/libxrpl/tx/wasm/host_functions/AmmKeylet.cpp
Normal file
53
src/tests/libxrpl/tx/wasm/host_functions/AmmKeylet.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct AmmKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(AmmKeyletImpl, MatchesAmmKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto usdIssue = Issue{toCurrency("USD"), owner.id()};
|
||||
|
||||
auto const expected = keylet::amm(xrpIssue(), usdIssue);
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().ammKeylet(usdIssue, xrpIssue());
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(AmmKeyletImpl, InvalidIssue1)
|
||||
{
|
||||
auto const result = host().ammKeylet(xrpIssue(), xrpIssue());
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidParams);
|
||||
}
|
||||
|
||||
TEST_F(AmmKeyletImpl, InvalidIssue2)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto baseMpt = makeMptID(1, owner.id());
|
||||
|
||||
auto const result = host().ammKeylet(baseMpt, xrpIssue());
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidParams);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
19
src/tests/libxrpl/tx/wasm/host_functions/BaseFee.cpp
Normal file
19
src/tests/libxrpl/tx/wasm/host_functions/BaseFee.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct BaseFeeImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(BaseFeeImpl, MatchesLedger)
|
||||
{
|
||||
auto const result = host().getBaseFee();
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, ledger.getOpenLedger().fees().base.drops());
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
81
src/tests/libxrpl/tx/wasm/host_functions/CacheLedgerObj.cpp
Normal file
81
src/tests/libxrpl/tx/wasm/host_functions/CacheLedgerObj.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct CacheLedgerObjImpl : WasmImplTest
|
||||
{
|
||||
void
|
||||
runMatchesLedger(bool implicit)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto& h = host();
|
||||
auto const key = keylet::account(owner.id()).key;
|
||||
|
||||
for (auto i = int32_t{1}; i < 257; ++i)
|
||||
{
|
||||
auto const slot = h.cacheLedgerObj(key, i);
|
||||
ASSERT_TRUE(slot.has_value()) << "cacheLedgerObj should find the created account";
|
||||
EXPECT_EQ(*slot, i);
|
||||
|
||||
auto const account = h.getLedgerObjField(*slot, sfAccount);
|
||||
ASSERT_TRUE(account.has_value());
|
||||
Bytes const ownerBytes{owner.id().begin(), owner.id().end()};
|
||||
EXPECT_EQ(*account, ownerBytes);
|
||||
|
||||
auto const sle = ledger.getOpenLedger().read(keylet::account(owner.id()));
|
||||
ASSERT_NE(sle, nullptr);
|
||||
auto const& ledgerAccount = sle->getAccountID(sfAccount);
|
||||
EXPECT_EQ(*account, (Bytes{ledgerAccount.begin(), ledgerAccount.end()}));
|
||||
}
|
||||
|
||||
// Every slot is now occupied, so asking to auto-allocate (cacheIdx == 0) has nowhere
|
||||
// to put the object.
|
||||
auto const result = h.cacheLedgerObj(key, 0);
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::SlotsFull);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CacheLedgerObjImpl, MatchesLedgerExplicitIndices)
|
||||
{
|
||||
runMatchesLedger(false);
|
||||
}
|
||||
|
||||
TEST_F(CacheLedgerObjImpl, MatchesLedgerImplicitIndices)
|
||||
{
|
||||
runMatchesLedger(true);
|
||||
}
|
||||
|
||||
TEST_F(CacheLedgerObjImpl, OutOfRange)
|
||||
{
|
||||
auto result = host().cacheLedgerObj(uint256{}, -1);
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::SlotOutRange);
|
||||
|
||||
result = host().cacheLedgerObj(uint256{}, 257);
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::SlotOutRange);
|
||||
}
|
||||
|
||||
TEST_F(CacheLedgerObjImpl, LedgerObjNotFound)
|
||||
{
|
||||
auto const ghost = keylet::account(Account{"ghost"}.id()).key;
|
||||
auto result = host().cacheLedgerObj(ghost, 0);
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::LedgerObjNotFound);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
40
src/tests/libxrpl/tx/wasm/host_functions/CheckKeylet.cpp
Normal file
40
src/tests/libxrpl/tx/wasm/host_functions/CheckKeylet.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct CheckKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(CheckKeyletImpl, MatchesCheckKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::check(owner.id(), SeqProxy::rawSequence(1u));
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().checkKeylet(owner.id(), 1u);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(CheckKeyletImpl, UnsetAccountIsInvalidAccount)
|
||||
{
|
||||
auto const result = host().checkKeylet(AccountID{}, 1u);
|
||||
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,69 @@
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct CredentialKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(CredentialKeyletImpl, MatchesCredentialKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const credTypeStr = std::string{"test"};
|
||||
auto const credType = Slice{credTypeStr.data(), credTypeStr.size()};
|
||||
|
||||
auto const expected = keylet::credential(owner.id(), owner.id(), credType);
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().credentialKeylet(owner.id(), owner.id(), credType);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(CredentialKeyletImpl, CredentialTypeStringTooLong)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto constexpr credTypeStr = std::string_view{
|
||||
"abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
|
||||
"asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p"};
|
||||
static_assert(credTypeStr.size() > kMaxCredentialTypeLength);
|
||||
auto const credType = Slice{credTypeStr.data(), credTypeStr.size()};
|
||||
|
||||
auto const result = host().credentialKeylet(owner.id(), owner.id(), credType);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidParams);
|
||||
}
|
||||
|
||||
TEST_F(CredentialKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const credTypeStr = std::string{"test"};
|
||||
auto const credType = Slice{credTypeStr.data(), credTypeStr.size()};
|
||||
|
||||
auto result = host().credentialKeylet(AccountID{}, owner.id(), credType);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
|
||||
result = host().credentialKeylet(owner.id(), AccountID{}, credType);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,108 @@
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol_autogen/transactions/EscrowCreate.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct CurrentLedgerObjFieldImpl : WasmImplTest
|
||||
{
|
||||
// Create an escrow owned by `owner` and return its keylet (the object the host will
|
||||
// read as its "current" object).
|
||||
Keylet
|
||||
makeEscrow(Account const& owner, Account const& dest, uint256* transactionId = nullptr)
|
||||
{
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
ledger.createAccount(dest, XRP(1000));
|
||||
|
||||
auto const ownerSeq = ledger.getAccountRoot(owner.id()).getSequence();
|
||||
// A finish time comfortably after the genesis close time.
|
||||
auto const r = ledger.submit(
|
||||
transactions::EscrowCreateBuilder{owner.id(), dest.id(), XRP(100)}.setFinishAfter(
|
||||
900'000'000),
|
||||
owner);
|
||||
EXPECT_EQ(r.ter, tesSUCCESS) << transToken(r.ter);
|
||||
if (transactionId != nullptr)
|
||||
{
|
||||
*transactionId = r.tx->getTransactionID();
|
||||
}
|
||||
ledger.close();
|
||||
return keylet::escrow(owner.id(), SeqProxy::rawSequence(ownerSeq));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CurrentLedgerObjFieldImpl, ReadsfAccount)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
auto const escrow = makeEscrow(owner, Account{"dest"});
|
||||
ASSERT_NE(ledger.getOpenLedger().read(escrow), nullptr) << "escrow object should exist";
|
||||
|
||||
auto const account = host(escrow).getCurrentLedgerObjField(sfAccount);
|
||||
|
||||
ASSERT_TRUE(account.has_value());
|
||||
auto const ownerBytes = Bytes{std::begin(owner.id()), std::end(owner.id())};
|
||||
EXPECT_EQ(*account, ownerBytes);
|
||||
}
|
||||
|
||||
TEST_F(CurrentLedgerObjFieldImpl, ReadsfAccountDummyEscrow)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
auto const ownerSeq = ledger.getAccountRoot(owner.id()).getSequence();
|
||||
auto const escrow = keylet::escrow(owner.id(), SeqProxy::rawSequence(ownerSeq));
|
||||
|
||||
auto const account = host(escrow).getCurrentLedgerObjField(sfAccount);
|
||||
|
||||
ASSERT_TRUE(!account.has_value());
|
||||
ASSERT_TRUE(account.error() == HostFunctionError::LedgerObjNotFound);
|
||||
}
|
||||
|
||||
TEST_F(CurrentLedgerObjFieldImpl, ReadAmount)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
auto const escrow = makeEscrow(owner, Account{"dest"});
|
||||
ASSERT_NE(ledger.getOpenLedger().read(escrow), nullptr) << "escrow object should exist";
|
||||
|
||||
auto const amount = host(escrow).getCurrentLedgerObjField(sfAmount);
|
||||
ASSERT_TRUE(amount.has_value());
|
||||
EXPECT_EQ(*amount, toBytes(XRP(100)));
|
||||
}
|
||||
|
||||
TEST_F(CurrentLedgerObjFieldImpl, ReadPreviousTxnID)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
auto transactionId = uint256{};
|
||||
auto const escrow = makeEscrow(owner, Account{"dest"}, &transactionId);
|
||||
ASSERT_NE(ledger.getOpenLedger().read(escrow), nullptr) << "escrow object should exist";
|
||||
|
||||
auto const previousTxnId = host(escrow).getCurrentLedgerObjField(sfPreviousTxnID);
|
||||
|
||||
ASSERT_TRUE(previousTxnId.has_value());
|
||||
EXPECT_EQ(*previousTxnId, toBytes(transactionId));
|
||||
}
|
||||
|
||||
TEST_F(CurrentLedgerObjFieldImpl, ReadOwner)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
auto const escrow = makeEscrow(owner, Account{"dest"});
|
||||
ASSERT_NE(ledger.getOpenLedger().read(escrow), nullptr) << "escrow object should exist";
|
||||
|
||||
auto const ownerField = host(escrow).getCurrentLedgerObjField(sfOwner);
|
||||
|
||||
ASSERT_TRUE(!ownerField.has_value());
|
||||
ASSERT_TRUE(ownerField.error() == HostFunctionError::FieldNotFound);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
57
src/tests/libxrpl/tx/wasm/host_functions/DelegateKeylet.cpp
Normal file
57
src/tests/libxrpl/tx/wasm/host_functions/DelegateKeylet.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct DelegateKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(DelegateKeyletImpl, MatchesDelegateKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
auto const delegate = Account{"delegate"};
|
||||
ledger.createAccount(delegate, XRP(1000));
|
||||
|
||||
auto const expected = keylet::delegate(owner.id(), delegate.id());
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().delegateKeylet(owner.id(), delegate.id());
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(DelegateKeyletImpl, CantDelegateToSelf)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const result = host().delegateKeylet(owner.id(), owner.id());
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidParams);
|
||||
}
|
||||
|
||||
TEST_F(DelegateKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto result = host().delegateKeylet(AccountID{}, owner.id());
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
|
||||
result = host().delegateKeylet(owner.id(), AccountID{});
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct DepositPreauthKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(DepositPreauthKeyletImpl, MatchesDepositPreauthKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
auto const destination = Account{"destination"};
|
||||
ledger.createAccount(destination, XRP(1000));
|
||||
|
||||
auto const expected = keylet::depositPreauth(owner.id(), destination.id());
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().depositPreauthKeylet(owner.id(), destination.id());
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(DepositPreauthKeyletImpl, CantPreauthToSelf)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const result = host().depositPreauthKeylet(owner.id(), owner.id());
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidParams);
|
||||
}
|
||||
|
||||
TEST_F(DepositPreauthKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto result = host().depositPreauthKeylet(AccountID{}, owner.id());
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
|
||||
result = host().depositPreauthKeylet(owner.id(), AccountID{});
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
38
src/tests/libxrpl/tx/wasm/host_functions/DidKeylet.cpp
Normal file
38
src/tests/libxrpl/tx/wasm/host_functions/DidKeylet.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct DidKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(DidKeyletImpl, MatchesDidKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::did(owner.id());
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().didKeylet(owner.id());
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(DidKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto result = host().didKeylet(AccountID{});
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
50
src/tests/libxrpl/tx/wasm/host_functions/EscrowKeylet.cpp
Normal file
50
src/tests/libxrpl/tx/wasm/host_functions/EscrowKeylet.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct EscrowKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(EscrowKeyletImpl, MatchesLedgerKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
auto const seq = std::uint32_t{42};
|
||||
|
||||
auto const result = host().escrowKeylet(owner.id(), seq);
|
||||
|
||||
ASSERT_TRUE(result.has_value());
|
||||
auto const expected = keylet::escrow(owner.id(), SeqProxy::rawSequence(seq)).key;
|
||||
auto const expectedBytes = Bytes{std::begin(expected), std::end(expected)};
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(EscrowKeyletImpl, DifferentAccountsGiveDifferentKeylets)
|
||||
{
|
||||
auto const a = host().escrowKeylet(Account{"alice"}.id(), 7);
|
||||
auto const b = host().escrowKeylet(Account{"becky"}.id(), 7);
|
||||
|
||||
ASSERT_TRUE(a.has_value() && b.has_value());
|
||||
EXPECT_NE(*a, *b);
|
||||
}
|
||||
|
||||
TEST_F(EscrowKeyletImpl, UnsetAccountIsInvalidAccount)
|
||||
{
|
||||
auto const result = host().escrowKeylet(AccountID{}, 1);
|
||||
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,50 @@
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <string_view>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct IsAmendmentEnabledImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(IsAmendmentEnabledImpl, EnabledAmendmentByIdReadsOne)
|
||||
{
|
||||
auto const id = getRegisteredFeature("TokenEscrow");
|
||||
ASSERT_TRUE(id.has_value());
|
||||
auto const result = host().isAmendmentEnabled(id.value_or(uint256{}));
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 1);
|
||||
}
|
||||
|
||||
TEST_F(IsAmendmentEnabledImpl, EnabledAmendmentByNameReadsOne)
|
||||
{
|
||||
auto const result = host().isAmendmentEnabled(std::string_view{"TokenEscrow"});
|
||||
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 1);
|
||||
}
|
||||
|
||||
TEST_F(IsAmendmentEnabledImpl, UnknownAmendmentByIdReadsZero)
|
||||
{
|
||||
auto const result = host().isAmendmentEnabled(
|
||||
uint256{"DEADBEEF00000000000000000000000000000000000000000000000000000000"});
|
||||
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 0);
|
||||
}
|
||||
|
||||
TEST_F(IsAmendmentEnabledImpl, UnknownAmendmentNameReadsZero)
|
||||
{
|
||||
auto const result = host().isAmendmentEnabled(std::string_view{"DEADBEEF"});
|
||||
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 0);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
19
src/tests/libxrpl/tx/wasm/host_functions/LedgerSqn.cpp
Normal file
19
src/tests/libxrpl/tx/wasm/host_functions/LedgerSqn.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct LedgerSqnImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(LedgerSqnImpl, MatchesLedger)
|
||||
{
|
||||
auto const result = host().getLedgerSqn();
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, ledger.getOpenLedger().header().seq);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct MptokenIssuanceKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(MptokenIssuanceKeyletImpl, MatchesMptokenIssuanceKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::mptokenIssuance(makeMptID(1u, owner.id()));
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().mptokenIssuanceKeylet(owner.id(), 1u);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(MptokenIssuanceKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto result = host().mptokenIssuanceKeylet(AccountID{}, 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
54
src/tests/libxrpl/tx/wasm/host_functions/MptokenKeylet.cpp
Normal file
54
src/tests/libxrpl/tx/wasm/host_functions/MptokenKeylet.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct MptokenKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(MptokenKeyletImpl, MatchesMptokenKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
auto const anotherAccount = Account{"account"};
|
||||
ledger.createAccount(anotherAccount, XRP(1000));
|
||||
|
||||
auto const mpt = makeMptID(1u, owner.id());
|
||||
auto const expected = keylet::mptoken(mpt, anotherAccount.id());
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().mptokenKeylet(mpt, anotherAccount.id());
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(MptokenKeyletImpl, InvalidMpt)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
auto result = host().mptokenKeylet(MPTID{}, owner.id());
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidParams);
|
||||
}
|
||||
|
||||
TEST_F(MptokenKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const mpt = makeMptID(1u, owner.id());
|
||||
auto result = host().mptokenKeylet(mpt, AccountID{});
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
39
src/tests/libxrpl/tx/wasm/host_functions/NFT.cpp
Normal file
39
src/tests/libxrpl/tx/wasm/host_functions/NFT.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct NFTImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(NFTImpl, MatchesVaultFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::vault(owner.id(), SeqProxy::rawSequence(1u));
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().vaultKeylet(owner.id(), 1u);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(NFTImpl, InvalidAccount)
|
||||
{
|
||||
auto result = host().vaultKeylet(AccountID{}, 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct NftokenOfferKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(NftokenOfferKeyletImpl, MatchesNftokenOfferFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::nftokenOffer(owner.id(), SeqProxy::rawSequence(1u));
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().nftokenOfferKeylet(owner.id(), 1u);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(NftokenOfferKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto result = host().nftokenOfferKeylet(AccountID{}, 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
39
src/tests/libxrpl/tx/wasm/host_functions/OfferKeylet.cpp
Normal file
39
src/tests/libxrpl/tx/wasm/host_functions/OfferKeylet.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct OfferKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(OfferKeyletImpl, MatchesOfferFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::offer(owner.id(), SeqProxy::rawSequence(1u));
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().offerKeylet(owner.id(), 1u);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(OfferKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto result = host().offerKeylet(AccountID{}, 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
38
src/tests/libxrpl/tx/wasm/host_functions/OracleKeylet.cpp
Normal file
38
src/tests/libxrpl/tx/wasm/host_functions/OracleKeylet.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct OracleKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(OracleKeyletImpl, MatchesOracleFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::oracle(owner.id(), 1u);
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().oracleKeylet(owner.id(), 1u);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(OracleKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto result = host().oracleKeylet(AccountID{}, 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct ParentLedgerHashImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(ParentLedgerHashImpl, MatchesLedger)
|
||||
{
|
||||
auto const result = host().getParentLedgerHash();
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, ledger.getOpenLedger().header().parentHash);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct ParentLedgerTimeImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(ParentLedgerTimeImpl, MatchesLedger)
|
||||
{
|
||||
auto const result = host().getParentLedgerTime();
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, ledger.getOpenLedger().parentCloseTime().time_since_epoch().count());
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct PaychannelKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(PaychannelKeyletImpl, MatchesPaychannelFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
auto const destination = Account{"destination"};
|
||||
ledger.createAccount(destination, XRP(1000));
|
||||
|
||||
auto const expected =
|
||||
keylet::payChannel(owner.id(), destination.id(), SeqProxy::rawSequence(1u));
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().paychannelKeylet(owner.id(), destination.id(), 1u);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(PaychannelKeyletImpl, CantUseSelf)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto result = host().paychannelKeylet(owner.id(), owner.id(), 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidParams);
|
||||
}
|
||||
|
||||
TEST_F(PaychannelKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto result = host().paychannelKeylet(AccountID{}, owner.id(), 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
|
||||
result = host().paychannelKeylet(owner.id(), AccountID{}, 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct PermissionedDomainKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(PermissionedDomainKeyletImpl, MatchesPermissionedDomainFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::permissionedDomain(owner.id(), SeqProxy::rawSequence(1u));
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().permissionedDomainKeylet(owner.id(), 1u);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(PermissionedDomainKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto result = host().permissionedDomainKeylet(AccountID{}, 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct SignerListKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(SignerListKeyletImpl, MatchesSignerListFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::signerList(owner.id());
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().signerListKeylet(owner.id());
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(SignerListKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto result = host().signerListKeylet(AccountID{});
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
39
src/tests/libxrpl/tx/wasm/host_functions/TicketKeylet.cpp
Normal file
39
src/tests/libxrpl/tx/wasm/host_functions/TicketKeylet.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct TicketKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(TicketKeyletImpl, MatchesTicketFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::ticket(owner.id(), SeqProxy::rawTicket(1u));
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().ticketKeylet(owner.id(), 1u);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(TicketKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto result = host().ticketKeylet(AccountID{}, 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
76
src/tests/libxrpl/tx/wasm/host_functions/TrustLineKeylet.cpp
Normal file
76
src/tests/libxrpl/tx/wasm/host_functions/TrustLineKeylet.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct TrustlineKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(TrustlineKeyletImpl, MatchesTrustlineKeyletFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
auto const destination = Account{"destination"};
|
||||
ledger.createAccount(destination, XRP(1000));
|
||||
|
||||
auto const usd = toCurrency("USD");
|
||||
|
||||
auto const expected = keylet::trustLine(owner.id(), destination.id(), usd);
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().trustLineKeylet(owner.id(), destination.id(), usd);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(TrustlineKeyletImpl, InvalidCurrency)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
auto const destination = Account{"destination"};
|
||||
ledger.createAccount(destination, XRP(1000));
|
||||
|
||||
auto const result = host().trustLineKeylet(owner.id(), destination.id(), toCurrency(""));
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidParams);
|
||||
}
|
||||
|
||||
TEST_F(TrustlineKeyletImpl, CantTrustlineToSelf)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const usd = toCurrency("USD");
|
||||
|
||||
auto const result = host().trustLineKeylet(owner.id(), owner.id(), usd);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidParams);
|
||||
}
|
||||
|
||||
TEST_F(TrustlineKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const usd = toCurrency("USD");
|
||||
|
||||
auto result = host().trustLineKeylet(AccountID{}, owner.id(), usd);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
|
||||
result = host().trustLineKeylet(owner.id(), AccountID{}, usd);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
82
src/tests/libxrpl/tx/wasm/host_functions/TxField.cpp
Normal file
82
src/tests/libxrpl/tx/wasm/host_functions/TxField.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct CacheLedgerObjImpl : WasmImplTest
|
||||
{
|
||||
void
|
||||
runMatchesLedger(bool implicit)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto& h = host();
|
||||
auto const key = keylet::account(owner.id()).key;
|
||||
|
||||
for (auto i = int32_t{1}; i < 257; ++i)
|
||||
{
|
||||
auto const slot = h.cacheLedgerObj(key, i);
|
||||
ASSERT_TRUE(slot.has_value()) << "cacheLedgerObj should find the created account";
|
||||
EXPECT_EQ(*slot, i);
|
||||
|
||||
auto const account = h.getLedgerObjField(*slot, sfAccount);
|
||||
ASSERT_TRUE(account.has_value());
|
||||
Bytes const ownerBytes{owner.id().begin(), owner.id().end()};
|
||||
EXPECT_EQ(*account, ownerBytes);
|
||||
|
||||
auto const sle = ledger.getOpenLedger().read(keylet::account(owner.id()));
|
||||
ASSERT_NE(sle, nullptr);
|
||||
auto const& ledgerAccount = sle->getAccountID(sfAccount);
|
||||
EXPECT_EQ(*account, (Bytes{ledgerAccount.begin(), ledgerAccount.end()}));
|
||||
}
|
||||
|
||||
// Every slot is now occupied, so asking to auto-allocate (cacheIdx == 0) has nowhere
|
||||
// to put the object.
|
||||
auto const result = h.cacheLedgerObj(key, 0);
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::SlotsFull);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CacheLedgerObjImpl, MatchesLedgerExplicitIndices)
|
||||
{
|
||||
runMatchesLedger(false);
|
||||
}
|
||||
|
||||
TEST_F(CacheLedgerObjImpl, MatchesLedgerImplicitIndices)
|
||||
{
|
||||
runMatchesLedger(true);
|
||||
}
|
||||
|
||||
TEST_F(CacheLedgerObjImpl, OutOfRange)
|
||||
{
|
||||
auto result = host().cacheLedgerObj(uint256{}, -1);
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::SlotOutRange);
|
||||
|
||||
result = host().cacheLedgerObj(uint256{}, 257);
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::SlotOutRange);
|
||||
}
|
||||
|
||||
TEST_F(CacheLedgerObjImpl, LedgerObjNotFound)
|
||||
{
|
||||
auto const ghost = keylet::account(Account{"ghost"}.id()).key;
|
||||
auto result = host().cacheLedgerObj(ghost, 0);
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::LedgerObjNotFound);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
35
src/tests/libxrpl/tx/wasm/host_functions/UpdateData.cpp
Normal file
35
src/tests/libxrpl/tx/wasm/host_functions/UpdateData.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct UpdateDataImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(UpdateDataImpl, SmallData)
|
||||
{
|
||||
auto& h = host();
|
||||
auto data = Bytes(10, 0x42);
|
||||
auto result = h.updateData(Slice{data.data(), data.size()});
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, data.size());
|
||||
// TODO: getData() does not seem to be called when the smart escrow finishes.
|
||||
EXPECT_EQ(h.getData(), data);
|
||||
}
|
||||
|
||||
TEST_F(UpdateDataImpl, LargeData)
|
||||
{
|
||||
auto& h = host();
|
||||
auto data = Bytes(kMaxWasmDataLength + 1, 0x42);
|
||||
auto result = h.updateData(Slice{data.data(), data.size()});
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::DataFieldTooLarge);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
39
src/tests/libxrpl/tx/wasm/host_functions/VaultKeylet.cpp
Normal file
39
src/tests/libxrpl/tx/wasm/host_functions/VaultKeylet.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/tx/wasm/WasmCommon.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/Account.h>
|
||||
#include <helpers/TxTest.h>
|
||||
#include <tx/wasm/RealHostFixture.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
struct VaultKeyletImpl : WasmImplTest
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(VaultKeyletImpl, MatchesVaultFunction)
|
||||
{
|
||||
auto const owner = Account{"owner"};
|
||||
ledger.createAccount(owner, XRP(1000));
|
||||
|
||||
auto const expected = keylet::vault(owner.id(), SeqProxy::rawSequence(1u));
|
||||
auto const expectedBytes = Bytes{std::begin(expected.key), std::end(expected.key)};
|
||||
auto const result = host().vaultKeylet(owner.id(), 1u);
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, expectedBytes);
|
||||
}
|
||||
|
||||
TEST_F(VaultKeyletImpl, InvalidAccount)
|
||||
{
|
||||
auto result = host().vaultKeylet(AccountID{}, 1u);
|
||||
ASSERT_TRUE(!result.has_value());
|
||||
EXPECT_EQ(result.error(), HostFunctionError::InvalidAccount);
|
||||
}
|
||||
|
||||
} // namespace xrpl::test
|
||||
Reference in New Issue
Block a user