chore: Address review comments

This commit is contained in:
TimothyBanks
2026-08-19 16:04:31 -04:00
parent ec64f23736
commit 82876ca47c
47 changed files with 455 additions and 320 deletions

View File

@@ -7,16 +7,16 @@
#include <cstdint>
#include <limits>
#include <string>
#include <string_view>
namespace xrpl::test {
struct FloatTest : WasmImplTest
struct FloatTest : RealHostFixture
{
static constexpr std::int64_t kMin64 = std::numeric_limits<std::int64_t>::min();
static constexpr std::int64_t kMax64 = std::numeric_limits<std::int64_t>::max();
static constexpr std::int32_t kNormalExp = 18;
static inline std::string const kInvalidData = "invalid_data";
static constexpr std::string_view const kInvalidData = "invalid_data";
// clang-format off
static inline Bytes const kIntMin = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}; // -2^63 (rounds to -(2^63-1))

View File

@@ -0,0 +1,52 @@
#include <tx/wasm/NFTFixture.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/nft.h>
#include <xrpl/protocol_autogen/transactions/NFTokenMint.h> // IWYU pragma: keep
#include <xrpl/tx/transactors/nft/NFTokenMint.h>
#include <gtest/gtest.h>
#include <helpers/Account.h>
#include <optional>
#include <string_view>
namespace xrpl::test {
uint256
NFTTest::makeNftId(AccountID const& issuer)
{
return NFTokenMint::createNFTokenID(kFlags, kFee, issuer, nft::toTaxon(kTaxon), kSequence);
}
uint256
NFTTest::mintNFT(Account const& issuer, std::optional<std::string_view> uri)
{
auto builder = transactions::NFTokenMintBuilder{issuer.id(), 0u};
if (uri)
builder.setURI(Slice{uri->data(), uri->size()});
auto const r = ledger.submit(builder, issuer);
EXPECT_EQ(r.ter, tesSUCCESS) << transToken(r.ter);
ledger.close();
// The single minted token lives in the owner's first NFTokenPage.
auto const& view = ledger.getOpenLedger();
auto const first = keylet::nftokenPageMin(issuer.id()).key;
auto const last = keylet::nftokenPageMax(issuer.id()).key;
auto const pageKey = view.succ(first, last.next());
EXPECT_TRUE(pageKey.has_value());
auto const page = pageKey ? view.read(Keylet{ltNFTOKEN_PAGE, *pageKey}) : nullptr;
EXPECT_NE(page, nullptr);
if (!page)
return uint256{};
auto const& tokens = page->getFieldArray(sfNFTokens);
EXPECT_FALSE(tokens.empty());
return tokens.empty() ? uint256{} : tokens[0].getFieldH256(sfNFTokenID);
}
} // namespace xrpl::test

View File

@@ -1,21 +1,10 @@
#pragma once
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/nft.h>
#include <xrpl/protocol_autogen/transactions/NFTokenMint.h>
#include <xrpl/tx/transactors/nft/NFTokenMint.h>
#include <gtest/gtest.h>
#include <helpers/Account.h>
#include <helpers/TxTest.h>
#include <tx/wasm/RealHostFixture.h>
#include <cstdint>
@@ -24,7 +13,7 @@
namespace xrpl::test {
struct NFTTest : WasmImplTest
struct NFTTest : RealHostFixture
{
static constexpr std::uint16_t kFlags = nft::kFlagTransferable | nft::kFlagBurnable;
static constexpr std::uint16_t kFee = 314;
@@ -32,38 +21,13 @@ struct NFTTest : WasmImplTest
static constexpr std::uint32_t kSequence = 7;
static uint256
makeNftId(AccountID const& issuer)
{
return NFTokenMint::createNFTokenID(kFlags, kFee, issuer, nft::toTaxon(kTaxon), kSequence);
}
makeNftId(AccountID const& issuer);
// Mint a real NFToken owned by `issuer` (taxon 0) and return its id, read back from the
// owner's NFTokenPage. TxTest applies to the open ledger, which produces no metadata, so
// the id is recovered from ledger state rather than from the mint's metadata.
uint256
mintNFT(Account const& issuer, std::optional<std::string_view> uri = std::nullopt)
{
auto builder = transactions::NFTokenMintBuilder{issuer.id(), 0u};
if (uri)
builder.setURI(Slice{uri->data(), uri->size()});
auto const r = ledger.submit(builder, issuer);
EXPECT_EQ(r.ter, tesSUCCESS) << transToken(r.ter);
ledger.close();
// The single minted token lives in the owner's first NFTokenPage.
auto const& view = ledger.getOpenLedger();
auto const first = keylet::nftokenPageMin(issuer.id()).key;
auto const last = keylet::nftokenPageMax(issuer.id()).key;
auto const pageKey = view.succ(first, last.next());
EXPECT_TRUE(pageKey.has_value());
auto const page = pageKey ? view.read(Keylet{ltNFTOKEN_PAGE, *pageKey}) : nullptr;
EXPECT_NE(page, nullptr);
if (!page)
return uint256{};
auto const& tokens = page->getFieldArray(sfNFTokens);
EXPECT_FALSE(tokens.empty());
return tokens.empty() ? uint256{} : tokens[0].getFieldH256(sfNFTokenID);
}
mintNFT(Account const& issuer, std::optional<std::string_view> uri = std::nullopt);
};
} // namespace xrpl::test

View File

@@ -0,0 +1,297 @@
#include <tx/wasm/RealHostFixture.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/KeyType.h>
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STNumber.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/SecretKey.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFormats.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol_autogen/transactions/SignerListSet.h> // IWYU pragma: keep
#include <xrpl/tx/ApplyContext.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <gtest/gtest.h>
#include <helpers/Account.h>
#include <helpers/TxTest.h>
#include <cstdint>
#include <expected>
#include <functional>
#include <iterator>
#include <memory>
#include <span>
#include <string_view>
#include <utility>
#include <vector>
namespace xrpl::test {
Bytes
toBytes(std::uint8_t value)
{
return {value};
}
Bytes
toBytes(std::uint16_t value)
{
return {static_cast<std::uint8_t>(value), static_cast<std::uint8_t>(value >> 8)};
}
Bytes
toBytes(std::uint32_t value)
{
return {
static_cast<std::uint8_t>(value),
static_cast<std::uint8_t>(value >> 8),
static_cast<std::uint8_t>(value >> 16),
static_cast<std::uint8_t>(value >> 24)};
}
Bytes
toBytes(uint256 const& value)
{
return Bytes{std::begin(value), std::end(value)};
}
Bytes
toBytes(std::string_view value)
{
return Bytes{std::begin(value), std::end(value)};
}
Bytes
toBytes(std::span<std::uint8_t const> value)
{
return Bytes{std::begin(value), std::end(value)};
}
Bytes
toBytes(AccountID const& account)
{
return Bytes{std::begin(account), std::end(account)};
}
Bytes
toBytes(Issue const& issue)
{
auto s = Serializer{};
s.addBitString(issue.currency);
if (!isXRP(issue.currency))
s.addBitString(issue.account);
return s.getData();
}
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()};
}
Bytes
toBytes(STAmount const& amount)
{
auto msg = Serializer{};
amount.add(msg);
return msg.getData();
}
Bytes
toBytes(STNumber const& number)
{
auto msg = Serializer{};
number.add(msg);
return msg.getData();
}
void
expectKeyletMatches(std::expected<Bytes, HostFunctionError> const& result, Keylet const& expected)
{
expectValue(result, toBytes(expected.key));
}
SignedMessage
signMessage(std::string_view message, KeyType keyType)
{
auto const [pk, sk] = randomKeyPair(keyType);
auto const msg = Bytes{std::begin(message), std::end(message)};
auto const sig = sign(pk, sk, Slice{msg.data(), msg.size()});
return {
.message = msg,
.signature = Bytes{sig.data(), sig.data() + sig.size()},
.publicKey = Bytes{pk.data(), pk.data() + pk.size()}};
}
uint256
credentialId(std::string_view hex)
{
auto id = uint256{};
EXPECT_TRUE(id.parseHex(std::string{hex}));
return id;
}
STObject
makeMemo(Bytes const& data)
{
auto memo = STObject::makeInnerObject(sfMemo);
memo.setFieldVL(sfMemoData, data);
return memo;
}
TxAssembler
bareTx(TxType type)
{
return {.type = type, .build = [](STObject&) {}};
}
TxAssembler
escrowFinishTx(TxTest& ledger, Account const& acct)
{
return {.type = ttESCROW_FINISH, .build = [&ledger, acct](STObject& obj) {
auto credId = uint256{};
EXPECT_TRUE(credId.parseHex(
"0011223344556677889900112233445566778899001122334455667788990011"));
obj.setAccountID(sfAccount, acct.id());
obj.setAccountID(sfOwner, acct.id());
obj.setFieldU32(sfOfferSequence, ledger.getAccountRoot(acct.id()).getSequence());
obj.setFieldArray(sfMemos, STArray{});
auto credIds = STVector256{};
credIds.pushBack(credId);
obj.setFieldV256(sfCredentialIDs, credIds);
}};
}
TxAssembler
ammDepositTx(Account const& acct, Asset const& asset1, Asset const& asset2)
{
return {.type = ttAMM_DEPOSIT, .build = [acct, asset1, asset2](STObject& obj) {
obj.setAccountID(sfAccount, acct.id());
obj.setFieldIssue(sfAsset, STIssue{sfAsset, asset1});
obj.setFieldIssue(sfAsset2, STIssue{sfAsset2, asset2});
}};
}
TxAssembler
mptIssuanceCreateTx(Account const& acct, std::uint8_t scale)
{
return {.type = ttMPTOKEN_ISSUANCE_CREATE, .build = [acct, scale](STObject& obj) {
obj.setAccountID(sfAccount, acct.id());
obj.setFieldU8(sfAssetScale, scale);
}};
}
WasmHost::WasmHost(
std::shared_ptr<STTx const> tx,
std::unique_ptr<ApplyContext> context,
std::unique_ptr<WasmHostFunctionsImpl> host)
: tx_{std::move(tx)}, context_{std::move(context)}, host_{std::move(host)}
{
}
WasmHostFunctionsImpl*
WasmHost::operator->() const
{
return host_.get();
}
WasmHostFunctionsImpl&
WasmHost::operator*() const
{
return *host_;
}
Account
RealHostFixture::fund(char const* name, XRPAmount amount)
{
auto const account = Account{name};
ledger.createAccount(account, amount);
return account;
}
WasmHost
RealHostFixture::makeHost(
beast::Journal journal,
Keylet const& leKey,
TxType txType,
std::function<void(STObject&)> assembler)
{
auto tx = std::make_shared<STTx>(
txType, [assembler = std::move(assembler)](STObject& obj) { assembler(obj); });
auto context = std::make_unique<ApplyContext>(
ledger.getServiceRegistry(),
ledger.getOpenLedger(),
*tx,
tesSUCCESS,
ledger.getOpenLedger().fees().base,
TapNone,
journal);
auto host = std::make_unique<WasmHostFunctionsImpl>(*context, leKey);
return WasmHost{std::move(tx), std::move(context), std::move(host)};
}
WasmHost
RealHostFixture::makeHost(
Keylet const& leKey,
TxType txType,
std::function<void(STObject&)> assembler)
{
return makeHost(
beast::Journal{beast::Journal::getNullSink()}, leKey, txType, std::move(assembler));
}
WasmHost
RealHostFixture::makeTracingHost(
Keylet const& leKey,
TxType txType,
std::function<void(STObject&)> assembler)
{
return makeHost(beast::Journal{traceSink_}, leKey, txType, std::move(assembler));
}
std::string
RealHostFixture::logged() const
{
return traceSink_.messages();
}
void
RealHostFixture::makeSignerList(
Account const& owner,
std::uint32_t quorum,
std::vector<std::pair<Account, std::uint16_t>> const& signers)
{
auto entries = STArray{};
for (auto const& [signer, weight] : signers)
{
auto entry = STObject::makeInnerObject(sfSignerEntry);
entry.setAccountID(sfAccount, signer.id());
entry.setFieldU16(sfSignerWeight, weight);
entries.push_back(std::move(entry));
}
auto const r = ledger.submit(
transactions::SignerListSetBuilder{owner.id(), quorum}.setSignerEntries(entries), owner);
EXPECT_EQ(r.ter, tesSUCCESS) << transToken(r.ter);
ledger.close();
}
} // namespace xrpl::test

View File

@@ -1,30 +1,20 @@
#pragma once
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ApplyView.h> // TapNone
#include <xrpl/protocol/AccountID.h>
#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/KeyType.h>
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/STNumber.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/SecretKey.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFormats.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol_autogen/transactions/SignerListSet.h>
#include <xrpl/tx/ApplyContext.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
#include <xrpl/tx/wasm/WasmCommon.h>
@@ -47,88 +37,28 @@
namespace xrpl::test {
inline Bytes
toBytes(std::uint8_t value)
{
return {value};
}
inline Bytes
toBytes(std::uint16_t value)
{
return {static_cast<std::uint8_t>(value), static_cast<std::uint8_t>(value >> 8)};
}
inline Bytes
toBytes(std::uint32_t value)
{
return {
static_cast<std::uint8_t>(value),
static_cast<std::uint8_t>(value >> 8),
static_cast<std::uint8_t>(value >> 16),
static_cast<std::uint8_t>(value >> 24)};
}
inline Bytes
toBytes(uint256 const& value)
{
return Bytes{std::begin(value), std::end(value)};
}
inline Bytes
toBytes(std::string_view value)
{
return Bytes{std::begin(value), std::end(value)};
}
inline Bytes
toBytes(std::span<std::uint8_t const> value)
{
return Bytes{std::begin(value), std::end(value)};
}
inline Bytes
toBytes(AccountID const& account)
{
return Bytes{std::begin(account), std::end(account)};
}
inline Bytes
toBytes(Issue const& issue)
{
auto s = Serializer{};
s.addBitString(issue.currency);
if (!isXRP(issue.currency))
s.addBitString(issue.account);
return s.getData();
}
inline 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()};
}
inline Bytes
toBytes(STAmount const& amount)
{
auto msg = Serializer{};
amount.add(msg);
return msg.getData();
}
inline Bytes
toBytes(STNumber const& number)
{
auto msg = Serializer{};
number.add(msg);
return msg.getData();
}
Bytes
toBytes(std::uint8_t value);
Bytes
toBytes(std::uint16_t value);
Bytes
toBytes(std::uint32_t value);
Bytes
toBytes(uint256 const& value);
Bytes
toBytes(std::string_view value);
Bytes
toBytes(std::span<std::uint8_t const> value);
Bytes
toBytes(AccountID const& account);
Bytes
toBytes(Issue const& issue);
Bytes
toBytes(Asset const& asset);
Bytes
toBytes(STAmount const& amount);
Bytes
toBytes(STNumber const& number);
template <typename T, typename U>
void
@@ -155,11 +85,8 @@ expectError(
EXPECT_EQ(result.error(), expected);
}
inline void
expectKeyletMatches(std::expected<Bytes, HostFunctionError> const& result, Keylet const& expected)
{
expectValue(result, toBytes(expected.key));
}
void
expectKeyletMatches(std::expected<Bytes, HostFunctionError> const& result, Keylet const& expected);
struct SignedMessage
{
@@ -168,34 +95,15 @@ struct SignedMessage
Bytes publicKey;
};
inline SignedMessage
signMessage(std::string_view message, KeyType keyType = KeyType::Secp256k1)
{
auto const [pk, sk] = randomKeyPair(keyType);
auto const msg = Bytes{std::begin(message), std::end(message)};
auto const sig = sign(pk, sk, Slice{msg.data(), msg.size()});
return {
.message = msg,
.signature = Bytes{sig.data(), sig.data() + sig.size()},
.publicKey = Bytes{pk.data(), pk.data() + pk.size()}};
}
SignedMessage
signMessage(std::string_view message, KeyType keyType = KeyType::Secp256k1);
inline uint256
uint256
credentialId(
std::string_view hex = "0011223344556677889900112233445566778899001122334455667788990011")
{
auto id = uint256{};
EXPECT_TRUE(id.parseHex(std::string{hex}));
return id;
}
std::string_view hex = "0011223344556677889900112233445566778899001122334455667788990011");
inline STObject
makeMemo(Bytes const& data)
{
auto memo = STObject::makeInnerObject(sfMemo);
memo.setFieldVL(sfMemoData, data);
return memo;
}
STObject
makeMemo(Bytes const& data);
struct TxAssembler
{
@@ -203,48 +111,14 @@ struct TxAssembler
std::function<void(STObject&)> build;
};
inline TxAssembler
bareTx(TxType type = ttESCROW_FINISH)
{
return {.type = type, .build = [](STObject&) {}};
}
inline TxAssembler
escrowFinishTx(TxTest& ledger, Account const& acct)
{
return {.type = ttESCROW_FINISH, .build = [&ledger, acct](STObject& obj) {
auto credId = uint256{};
EXPECT_TRUE(credId.parseHex(
"0011223344556677889900112233445566778899001122334455667788990011"));
obj.setAccountID(sfAccount, acct.id());
obj.setAccountID(sfOwner, acct.id());
obj.setFieldU32(sfOfferSequence, ledger.getAccountRoot(acct.id()).getSequence());
obj.setFieldArray(sfMemos, STArray{});
auto credIds = STVector256{};
credIds.pushBack(credId);
obj.setFieldV256(sfCredentialIDs, credIds);
}};
}
inline TxAssembler
ammDepositTx(Account const& acct, Asset const& asset1, Asset const& asset2)
{
return {.type = ttAMM_DEPOSIT, .build = [acct, asset1, asset2](STObject& obj) {
obj.setAccountID(sfAccount, acct.id());
obj.setFieldIssue(sfAsset, STIssue{sfAsset, asset1});
obj.setFieldIssue(sfAsset2, STIssue{sfAsset2, asset2});
}};
}
inline TxAssembler
mptIssuanceCreateTx(Account const& acct, std::uint8_t scale)
{
return {.type = ttMPTOKEN_ISSUANCE_CREATE, .build = [acct, scale](STObject& obj) {
obj.setAccountID(sfAccount, acct.id());
obj.setFieldU8(sfAssetScale, scale);
}};
}
TxAssembler
bareTx(TxType type = ttESCROW_FINISH);
TxAssembler
escrowFinishTx(TxTest& ledger, Account const& acct);
TxAssembler
ammDepositTx(Account const& acct, Asset const& asset1, Asset const& asset2);
TxAssembler
mptIssuanceCreateTx(Account const& acct, std::uint8_t scale);
class WasmHost
{
@@ -252,21 +126,12 @@ public:
WasmHost(
std::shared_ptr<STTx const> tx,
std::unique_ptr<ApplyContext> context,
std::unique_ptr<WasmHostFunctionsImpl> host)
: tx_{std::move(tx)}, context_{std::move(context)}, host_{std::move(host)}
{
}
std::unique_ptr<WasmHostFunctionsImpl> host);
WasmHostFunctionsImpl*
operator->() const
{
return host_.get();
}
operator->() const;
WasmHostFunctionsImpl&
operator*() const
{
return *host_;
}
operator*() const;
private:
std::shared_ptr<STTx const> tx_;
@@ -274,50 +139,27 @@ private:
std::unique_ptr<WasmHostFunctionsImpl> host_;
};
class WasmImplTest : public testing::Test
class RealHostFixture : public testing::Test
{
public:
TxTest ledger;
Account
fund(char const* name, XRPAmount amount = XRP(1000))
{
auto const account = Account{name};
ledger.createAccount(account, amount);
return account;
}
fund(char const* name, XRPAmount amount = XRP(1000));
WasmHost
makeHost(
beast::Journal journal,
Keylet const& leKey = keylet::account(AccountID{}),
TxType txType = ttESCROW_FINISH,
std::function<void(STObject&)> assembler = [](STObject&) {})
{
auto tx = std::make_shared<STTx>(
txType, [assembler = std::move(assembler)](STObject& obj) { assembler(obj); });
auto context = std::make_unique<ApplyContext>(
ledger.getServiceRegistry(),
ledger.getOpenLedger(),
*tx,
tesSUCCESS,
ledger.getOpenLedger().fees().base,
TapNone,
journal);
auto host = std::make_unique<WasmHostFunctionsImpl>(*context, leKey);
return WasmHost{std::move(tx), std::move(context), std::move(host)};
}
std::function<void(STObject&)> assembler = [](STObject&) {});
// The common case: a host that discards its log output.
WasmHost
makeHost(
Keylet const& leKey = keylet::account(AccountID{}),
TxType txType = ttESCROW_FINISH,
std::function<void(STObject&)> assembler = [](STObject&) {})
{
return makeHost(
beast::Journal{beast::Journal::getNullSink()}, leKey, txType, std::move(assembler));
}
std::function<void(STObject&)> assembler = [](STObject&) {});
// A host whose `trace` output is captured, so a test can read it back with `logged()`.
// The sink is a fixture member, so it outlives the host and accumulates across a test.
@@ -325,17 +167,11 @@ public:
makeTracingHost(
Keylet const& leKey = keylet::account(AccountID{}),
TxType txType = ttESCROW_FINISH,
std::function<void(STObject&)> assembler = [](STObject&) {})
{
return makeHost(beast::Journal{traceSink_}, leKey, txType, std::move(assembler));
}
std::function<void(STObject&)> assembler = [](STObject&) {});
// Everything `trace` has written to the tracing host so far.
[[nodiscard]] std::string
logged() const
{
return traceSink_.messages();
}
logged() const;
// Submit a real SignerListSet so `keylet::signerList(owner)` exists — the object the
// signer-list nested-field / array-length getters read. `signers` pairs each signer
@@ -344,22 +180,7 @@ public:
makeSignerList(
Account const& owner,
std::uint32_t quorum,
std::vector<std::pair<Account, std::uint16_t>> const& signers)
{
auto entries = STArray{};
for (auto const& [signer, weight] : signers)
{
auto entry = STObject::makeInnerObject(sfSignerEntry);
entry.setAccountID(sfAccount, signer.id());
entry.setFieldU16(sfSignerWeight, weight);
entries.push_back(std::move(entry));
}
auto const r = ledger.submit(
transactions::SignerListSetBuilder{owner.id(), quorum}.setSignerEntries(entries),
owner);
EXPECT_EQ(r.ter, tesSUCCESS) << transToken(r.ter);
ledger.close();
}
std::vector<std::pair<Account, std::uint16_t>> const& signers);
private:
CaptureSink traceSink_{beast::Severity::Trace};

View File

@@ -8,7 +8,7 @@
namespace xrpl::test {
struct AccountKeyletImpl : WasmImplTest
struct AccountKeyletImpl : RealHostFixture
{
};

View File

@@ -9,7 +9,7 @@
namespace xrpl::test {
struct AmmKeyletImpl : WasmImplTest
struct AmmKeyletImpl : RealHostFixture
{
};

View File

@@ -3,7 +3,7 @@
namespace xrpl::test {
struct BaseFeeImpl : WasmImplTest
struct BaseFeeImpl : RealHostFixture
{
};

View File

@@ -12,7 +12,7 @@
namespace xrpl::test {
struct CacheLedgerObjImpl : WasmImplTest
struct CacheLedgerObjImpl : RealHostFixture
{
void
runMatchesLedger(bool implicit)

View File

@@ -9,7 +9,7 @@
namespace xrpl::test {
struct CheckKeyletImpl : WasmImplTest
struct CheckKeyletImpl : RealHostFixture
{
};

View File

@@ -9,7 +9,7 @@
namespace xrpl::test {
struct CheckSignatureImpl : WasmImplTest
struct CheckSignatureImpl : RealHostFixture
{
};

View File

@@ -10,7 +10,7 @@
namespace xrpl::test {
struct CredentialKeyletImpl : WasmImplTest
struct CredentialKeyletImpl : RealHostFixture
{
};

View File

@@ -10,9 +10,9 @@
namespace xrpl::test {
struct CurrentLedgerObjArrayLenImpl : WasmImplTest
struct CurrentLedgerObjArrayLenImpl : RealHostFixture
{
using WasmImplTest::makeHost;
using RealHostFixture::makeHost;
WasmHost
makeHost(Account const& acct)

View File

@@ -14,7 +14,7 @@
namespace xrpl::test {
struct CurrentLedgerObjFieldImpl : WasmImplTest
struct CurrentLedgerObjFieldImpl : RealHostFixture
{
// Create an escrow owned by `owner` and return its keylet (the object the host will
// read as its "current" object).

View File

@@ -10,9 +10,9 @@
namespace xrpl::test {
struct CurrentLedgerObjNestedArrayLenImpl : WasmImplTest
struct CurrentLedgerObjNestedArrayLenImpl : RealHostFixture
{
using WasmImplTest::makeHost;
using RealHostFixture::makeHost;
WasmHost
makeHost(Account const& acct)

View File

@@ -13,9 +13,9 @@
namespace xrpl::test {
struct CurrentLedgerObjNestedFieldImpl : WasmImplTest
struct CurrentLedgerObjNestedFieldImpl : RealHostFixture
{
using WasmImplTest::makeHost;
using RealHostFixture::makeHost;
WasmHost
makeHost(Account const& acct)

View File

@@ -8,7 +8,7 @@
namespace xrpl::test {
struct DelegateKeyletImpl : WasmImplTest
struct DelegateKeyletImpl : RealHostFixture
{
};

View File

@@ -8,7 +8,7 @@
namespace xrpl::test {
struct DepositPreauthKeyletImpl : WasmImplTest
struct DepositPreauthKeyletImpl : RealHostFixture
{
};

View File

@@ -8,7 +8,7 @@
namespace xrpl::test {
struct DidKeyletImpl : WasmImplTest
struct DidKeyletImpl : RealHostFixture
{
};

View File

@@ -11,7 +11,7 @@
namespace xrpl::test {
struct EscrowKeyletImpl : WasmImplTest
struct EscrowKeyletImpl : RealHostFixture
{
};

View File

@@ -48,7 +48,8 @@ TEST_F(FloatFromStAmountImpl, MinusOneXrp)
TEST_F(FloatFromStAmountImpl, MaxDrops)
{
auto h = makeHost();
auto const expected = h->floatFromMantExp(9'223'372'036'854'776, 3, 0);
static constexpr int64_t kTestValue{9'223'372'036'854'776};
auto const expected = h->floatFromMantExp(kTestValue, 3, 0);
ASSERT_TRUE(expected.has_value());
expectValue(h->floatFromSTAmount(STAmount{noIssue(), kMax64}, 0), *expected);
}

View File

@@ -8,7 +8,7 @@
namespace xrpl::test {
struct IsAmendmentEnabledImpl : WasmImplTest
struct IsAmendmentEnabledImpl : RealHostFixture
{
};

View File

@@ -11,9 +11,9 @@
namespace xrpl::test {
struct LedgerObjArrayLenImpl : WasmImplTest
struct LedgerObjArrayLenImpl : RealHostFixture
{
using WasmImplTest::makeHost;
using RealHostFixture::makeHost;
WasmHost
makeHost(Account const& acct)

View File

@@ -12,7 +12,7 @@
namespace xrpl::test {
struct LedgerObjFieldImpl : WasmImplTest
struct LedgerObjFieldImpl : RealHostFixture
{
template <typename Functor>
void

View File

@@ -11,9 +11,9 @@
namespace xrpl::test {
struct LedgerObjNestedArrayLenImpl : WasmImplTest
struct LedgerObjNestedArrayLenImpl : RealHostFixture
{
using WasmImplTest::makeHost;
using RealHostFixture::makeHost;
WasmHost
makeHost(Account const& acct)

View File

@@ -14,9 +14,9 @@
namespace xrpl::test {
struct LedgerObjNestedFieldImpl : WasmImplTest
struct LedgerObjNestedFieldImpl : RealHostFixture
{
using WasmImplTest::makeHost;
using RealHostFixture::makeHost;
WasmHost
makeHost(Account const& acct)

View File

@@ -3,7 +3,7 @@
namespace xrpl::test {
struct LedgerSqnImpl : WasmImplTest
struct LedgerSqnImpl : RealHostFixture
{
};

View File

@@ -8,7 +8,7 @@
namespace xrpl::test {
struct MptokenIssuanceKeyletImpl : WasmImplTest
struct MptokenIssuanceKeyletImpl : RealHostFixture
{
};

View File

@@ -8,7 +8,7 @@
namespace xrpl::test {
struct MptokenKeyletImpl : WasmImplTest
struct MptokenKeyletImpl : RealHostFixture
{
};

View File

@@ -9,7 +9,7 @@
namespace xrpl::test {
struct NftokenOfferKeyletImpl : WasmImplTest
struct NftokenOfferKeyletImpl : RealHostFixture
{
};

View File

@@ -9,7 +9,7 @@
namespace xrpl::test {
struct OfferKeyletImpl : WasmImplTest
struct OfferKeyletImpl : RealHostFixture
{
};

View File

@@ -8,7 +8,7 @@
namespace xrpl::test {
struct OracleKeyletImpl : WasmImplTest
struct OracleKeyletImpl : RealHostFixture
{
};

View File

@@ -3,7 +3,7 @@
namespace xrpl::test {
struct ParentLedgerHashImpl : WasmImplTest
struct ParentLedgerHashImpl : RealHostFixture
{
};

View File

@@ -3,7 +3,7 @@
namespace xrpl::test {
struct ParentLedgerTimeImpl : WasmImplTest
struct ParentLedgerTimeImpl : RealHostFixture
{
};

View File

@@ -9,7 +9,7 @@
namespace xrpl::test {
struct PaychannelKeyletImpl : WasmImplTest
struct PaychannelKeyletImpl : RealHostFixture
{
};

View File

@@ -9,7 +9,7 @@
namespace xrpl::test {
struct PermissionedDomainKeyletImpl : WasmImplTest
struct PermissionedDomainKeyletImpl : RealHostFixture
{
};

View File

@@ -7,7 +7,7 @@
namespace xrpl::test {
struct Sha512HalfImpl : WasmImplTest
struct Sha512HalfImpl : RealHostFixture
{
};

View File

@@ -8,7 +8,7 @@
namespace xrpl::test {
struct SignerListKeyletImpl : WasmImplTest
struct SignerListKeyletImpl : RealHostFixture
{
};

View File

@@ -9,7 +9,7 @@
namespace xrpl::test {
struct TicketKeyletImpl : WasmImplTest
struct TicketKeyletImpl : RealHostFixture
{
};

View File

@@ -8,7 +8,7 @@
namespace xrpl::test {
struct TraceImpl : WasmImplTest
struct TraceImpl : RealHostFixture
{
};

View File

@@ -9,7 +9,7 @@
namespace xrpl::test {
struct TrustlineKeyletImpl : WasmImplTest
struct TrustlineKeyletImpl : RealHostFixture
{
};

View File

@@ -12,9 +12,9 @@
namespace xrpl::test {
struct TxArrayLenImpl : WasmImplTest
struct TxArrayLenImpl : RealHostFixture
{
using WasmImplTest::makeHost;
using RealHostFixture::makeHost;
WasmHost
makeHost(Account const& acct)

View File

@@ -17,7 +17,7 @@
namespace xrpl::test {
struct TxFieldImpl : WasmImplTest
struct TxFieldImpl : RealHostFixture
{
template <typename Functor>
void

View File

@@ -12,9 +12,9 @@
namespace xrpl::test {
struct TxNestedArrayLenImpl : WasmImplTest
struct TxNestedArrayLenImpl : RealHostFixture
{
using WasmImplTest::makeHost;
using RealHostFixture::makeHost;
WasmHost
makeHost(Account const& acct)

View File

@@ -15,7 +15,7 @@
namespace xrpl::test {
struct TxNestedFieldImpl : WasmImplTest
struct TxNestedFieldImpl : RealHostFixture
{
TxAssembler
assemble(Account const& acct)
@@ -32,7 +32,7 @@ struct TxNestedFieldImpl : WasmImplTest
return assembler;
}
using WasmImplTest::makeHost;
using RealHostFixture::makeHost;
WasmHost
makeHost(Account const& acct)

View File

@@ -6,7 +6,7 @@
namespace xrpl::test {
struct UpdateDataImpl : WasmImplTest
struct UpdateDataImpl : RealHostFixture
{
};

View File

@@ -9,7 +9,7 @@
namespace xrpl::test {
struct VaultKeyletImpl : WasmImplTest
struct VaultKeyletImpl : RealHostFixture
{
};