mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-03 17:05:50 +00:00
ledger and account rpc tests (#62)
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include <boost/logic/tribool.hpp>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <deque>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
|
||||
@@ -121,8 +121,10 @@ JSS(SetFlag); // field.
|
||||
JSS(SetRegularKey); // transaction type.
|
||||
JSS(SetHook); // transaction type.
|
||||
JSS(Hook); // ledger type.
|
||||
JSS(HookDefinition); // ledger type.
|
||||
JSS(HookState); // ledger type.
|
||||
JSS(HookDefinition);
|
||||
JSS(HookStateData); // field.
|
||||
JSS(HookStateKey); // field.
|
||||
JSS(EmittedTxn); // ledger type.
|
||||
JSS(SignerList); // ledger type.
|
||||
JSS(SignerListSet); // transaction type.
|
||||
@@ -283,6 +285,7 @@ JSS(error_code); // out: error
|
||||
JSS(error_exception); // out: Submit
|
||||
JSS(error_message); // out: error
|
||||
JSS(escrow); // in: LedgerEntry
|
||||
JSS(emitted_txn); // in: LedgerEntry
|
||||
JSS(expand); // in: handler/Ledger
|
||||
JSS(expected_date); // out: any (warnings)
|
||||
JSS(expected_date_UTC); // out: any (warnings)
|
||||
@@ -326,7 +329,9 @@ JSS(high); // out: BookChanges
|
||||
JSS(highest_sequence); // out: AccountInfo
|
||||
JSS(highest_ticket); // out: AccountInfo
|
||||
JSS(historical_perminute); // historical_perminute.
|
||||
JSS(hook_hash); // in: LedgerEntry
|
||||
JSS(hook); // in: LedgerEntry
|
||||
JSS(hook_definition); // in: LedgerEntry
|
||||
JSS(hook_state); // in: LedgerEntry
|
||||
JSS(hostid); // out: NetworkOPs
|
||||
JSS(hotwallet); // in: GatewayBalances
|
||||
JSS(id); // websocket.
|
||||
|
||||
@@ -217,6 +217,19 @@ doLedgerEntry(RPC::JsonContext& context)
|
||||
.key;
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::emitted_txn))
|
||||
{
|
||||
expectedType = ltEMITTED_TXN;
|
||||
if (!context.params[jss::emitted_txn].isObject())
|
||||
{
|
||||
if (!uNodeIndex.parseHex(context.params[jss::emitted_txn].asString()))
|
||||
{
|
||||
uNodeIndex = beast::zero;
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
uNodeIndex = keylet::emittedTxn(uNodeIndex).key;
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::offer))
|
||||
{
|
||||
expectedType = ltOFFER;
|
||||
@@ -337,11 +350,37 @@ doLedgerEntry(RPC::JsonContext& context)
|
||||
*id, context.params[jss::ticket][jss::ticket_seq].asUInt());
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::hook_hash))
|
||||
else if (context.params.isMember(jss::hook))
|
||||
{
|
||||
expectedType = ltHOOK;
|
||||
if (!context.params[jss::hook].isObject())
|
||||
{
|
||||
if (!uNodeIndex.parseHex(context.params[jss::hook].asString()))
|
||||
{
|
||||
uNodeIndex = beast::zero;
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
}
|
||||
else if (
|
||||
!context.params[jss::hook].isMember(jss::account))
|
||||
{
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const id = parseBase58<AccountID>(
|
||||
context.params[jss::hook][jss::account].asString());
|
||||
if (!id)
|
||||
jvResult[jss::error] = "malformedAddress";
|
||||
else
|
||||
uNodeIndex = keylet::hook(*id).key;
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::hook_definition))
|
||||
{
|
||||
expectedType = ltHOOK_DEFINITION;
|
||||
if (context.params[jss::hook_hash].isObject() ||
|
||||
(!uNodeIndex.parseHex(context.params[jss::hook_hash].asString())))
|
||||
if (context.params[jss::hook_definition].isObject() ||
|
||||
(!uNodeIndex.parseHex(context.params[jss::hook_definition].asString())))
|
||||
{
|
||||
uNodeIndex = beast::zero;
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
@@ -351,6 +390,45 @@ doLedgerEntry(RPC::JsonContext& context)
|
||||
uNodeIndex = keylet::hookDefinition(uNodeIndex).key;
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::hook_state))
|
||||
{
|
||||
expectedType = ltHOOK_STATE;
|
||||
uint256 uNodeKey;
|
||||
uint256 uNameSpace;
|
||||
Json::Value jvHookState = context.params[jss::hook_state];
|
||||
|
||||
if (!jvHookState.isObject() ||
|
||||
!jvHookState.isMember(jss::account) ||
|
||||
!jvHookState.isMember(jss::key) ||
|
||||
!jvHookState.isMember(jss::namespace_id) ||
|
||||
!jvHookState[jss::account].isString() ||
|
||||
!jvHookState[jss::key].isString() ||
|
||||
!jvHookState[jss::namespace_id].isString())
|
||||
{
|
||||
uNodeIndex = beast::zero;
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const account = parseBase58<AccountID>(jvHookState[jss::account].asString());
|
||||
if (!account)
|
||||
{
|
||||
jvResult[jss::error] = "malformedAddress";
|
||||
}
|
||||
else if (!uNodeKey.parseHex(jvHookState[jss::key].asString()))
|
||||
{
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
else if (!uNameSpace.parseHex(jvHookState[jss::namespace_id].asString()))
|
||||
{
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
else
|
||||
{
|
||||
uNodeIndex = keylet::hookState(*account, uNodeKey, uNameSpace).key;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::nft_page))
|
||||
{
|
||||
expectedType = ltNFTOKEN_PAGE;
|
||||
|
||||
@@ -1067,7 +1067,7 @@ chooseLedgerEntryType(Json::Value const& params)
|
||||
std::pair<RPC::Status, LedgerEntryType> result{RPC::Status::OK, ltANY};
|
||||
if (params.isMember(jss::type))
|
||||
{
|
||||
static constexpr std::array<std::pair<char const*, LedgerEntryType>, 15>
|
||||
static constexpr std::array<std::pair<char const*, LedgerEntryType>, 17>
|
||||
types{
|
||||
{{jss::account, ltACCOUNT_ROOT},
|
||||
{jss::amendments, ltAMENDMENTS},
|
||||
@@ -1075,6 +1075,9 @@ chooseLedgerEntryType(Json::Value const& params)
|
||||
{jss::deposit_preauth, ltDEPOSIT_PREAUTH},
|
||||
{jss::directory, ltDIR_NODE},
|
||||
{jss::escrow, ltESCROW},
|
||||
{jss::hook, ltHOOK},
|
||||
{jss::hook_definition, ltHOOK_DEFINITION},
|
||||
{jss::hook_state, ltHOOK_STATE},
|
||||
{jss::fee, ltFEE_SETTINGS},
|
||||
{jss::hashes, ltLEDGER_HASHES},
|
||||
{jss::offer, ltOFFER},
|
||||
|
||||
@@ -34,6 +34,9 @@ hook(Account const& account, std::optional<std::vector<Json::Value>> hooks, std:
|
||||
Json::Value
|
||||
hso(std::vector<uint8_t> const& wasmBytes, void (*f)(Json::Value& jv) = 0);
|
||||
|
||||
Json::Value
|
||||
hso(std::string const& wasmHex, void (*f)(Json::Value& jv) = 0);
|
||||
|
||||
Json::Value
|
||||
hso_delete(void (*f)(Json::Value& jv) = 0);
|
||||
|
||||
|
||||
@@ -80,6 +80,28 @@ hso(std::vector<uint8_t> const& wasmBytes, void (*f)(Json::Value& jv))
|
||||
|
||||
}
|
||||
|
||||
Json::Value
|
||||
hso(std::string const& wasmHex, void (*f)(Json::Value& jv))
|
||||
{
|
||||
|
||||
if (wasmHex.size() == 0)
|
||||
throw std::runtime_error("empty hook wasm passed to hso()");
|
||||
|
||||
Json::Value jv;
|
||||
jv[jss::CreateCode] = wasmHex;
|
||||
{
|
||||
jv[jss::HookOn] = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
jv[jss::HookNamespace] = to_string(uint256{beast::zero});
|
||||
jv[jss::HookApiVersion] = Json::Value{0};
|
||||
}
|
||||
|
||||
if (f)
|
||||
f(jv);
|
||||
|
||||
return jv;
|
||||
|
||||
}
|
||||
|
||||
} // namespace jtx
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/hook/Enum.h>
|
||||
#include <ripple/json/json_reader.h>
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
@@ -111,6 +112,7 @@ static char const* bobs_account_objects[] = {
|
||||
class AccountObjects_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
#define HSFEE fee(100'000'000)
|
||||
void
|
||||
testErrors()
|
||||
{
|
||||
@@ -586,6 +588,7 @@ public:
|
||||
BEAST_EXPECT(acct_objs_is_size(acct_objs(gw, jss::state), 0));
|
||||
BEAST_EXPECT(acct_objs_is_size(acct_objs(gw, jss::ticket), 0));
|
||||
BEAST_EXPECT(acct_objs_is_size(acct_objs(gw, jss::uri_token), 0));
|
||||
BEAST_EXPECT(acct_objs_is_size(acct_objs(gw, jss::hook), 0));
|
||||
|
||||
// gw mints an NFT so we can find it.
|
||||
uint256 const nftID{token::getNextID(env, gw, 0u, tfTransferable)};
|
||||
@@ -755,6 +758,23 @@ public:
|
||||
BEAST_EXPECT(uritoken[sfIssuer.jsonName] == gw.human());
|
||||
BEAST_EXPECT(uritoken[sfURI.jsonName] == strHex(uri));
|
||||
}
|
||||
{
|
||||
// Create hook
|
||||
auto setHook = [](test::jtx::Account const& account) {
|
||||
std::string const createCodeHex = "0061736D0100000001130360037F7F7E017E60027F7F017F60017F017E02170203656E7606616363657074000003656E76025F670001030201020503010002062B077F01418088040B7F004180080B7F004180080B7F004180080B7F00418088040B7F0041000B7F0041010B07080104686F6F6B00020AB5800001B1800001017F230041106B220124002001200036020C410022002000420010001A41012200200010011A200141106A240042000B";
|
||||
Json::Value jv = ripple::test::jtx::hook(account, {{hso(createCodeHex)}}, 0);
|
||||
return jv;
|
||||
};
|
||||
env(setHook(gw), HSFEE);
|
||||
env.close();
|
||||
}
|
||||
{
|
||||
// Find the hook.
|
||||
Json::Value const resp = acct_objs(gw, jss::hook);
|
||||
BEAST_EXPECT(acct_objs_is_size(resp, 1));
|
||||
auto const& hook = resp[jss::result][jss::account_objects][0u];
|
||||
BEAST_EXPECT(hook[sfAccount.jsonName] == gw.human());
|
||||
}
|
||||
{
|
||||
// See how "deletion_blockers_only" handles gw's directory.
|
||||
Json::Value params;
|
||||
@@ -765,6 +785,7 @@ public:
|
||||
std::vector<std::string> const expectedLedgerTypes = [] {
|
||||
std::vector<std::string> v{
|
||||
jss::Escrow.c_str(),
|
||||
jss::Hook.c_str(),
|
||||
jss::Check.c_str(),
|
||||
jss::NFTokenPage.c_str(),
|
||||
jss::RippleState.c_str(),
|
||||
@@ -811,7 +832,7 @@ public:
|
||||
// directory nodes.
|
||||
for (int d = 1'000'032; d >= 1'000'000; --d)
|
||||
{
|
||||
env(offer(gw, USD(1), drops(d)));
|
||||
env(offer(gw, USD(1), drops(d)), HSFEE);
|
||||
env.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/app/misc/TxQ.h>
|
||||
#include <ripple/protocol/ErrorCodes.h>
|
||||
#include <ripple/protocol/jss.h>
|
||||
#include <ripple/rpc/impl/RPCHelpers.h>
|
||||
#include <ripple/app/hook/Enum.h>
|
||||
#include <ripple/protocol/jss.h>
|
||||
#include <test/jtx.h>
|
||||
|
||||
#include <boost/container/flat_set.hpp>
|
||||
@@ -31,6 +33,8 @@ namespace test {
|
||||
|
||||
class AccountTx_test : public beast::unit_test::suite
|
||||
{
|
||||
#define HSFEE fee(100'000'000)
|
||||
|
||||
// A data structure used to describe the basic structure of a
|
||||
// transactions array node as returned by the account_tx RPC command.
|
||||
struct NodeSanity
|
||||
@@ -101,7 +105,6 @@ class AccountTx_test : public beast::unit_test::suite
|
||||
__FILE__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
BEAST_EXPECT(createdNodes == sane.created);
|
||||
BEAST_EXPECT(deletedNodes == sane.deleted);
|
||||
BEAST_EXPECT(modifiedNodes == sane.modified);
|
||||
@@ -393,6 +396,8 @@ class AccountTx_test : public beast::unit_test::suite
|
||||
env(check::cancel(alice, aliceCheckId), sig(alie));
|
||||
env.close();
|
||||
}
|
||||
|
||||
// Ticket
|
||||
{
|
||||
// Deposit preauthorization with a Ticket.
|
||||
std::uint32_t const tktSeq{env.seq(alice) + 1};
|
||||
@@ -403,7 +408,138 @@ class AccountTx_test : public beast::unit_test::suite
|
||||
env.close();
|
||||
}
|
||||
|
||||
// Setup is done. Look at the transactions returned by account_tx.
|
||||
// URIToken
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
std::string const uri(maxTokenURILength, '?');
|
||||
|
||||
// Mint URIToken
|
||||
auto mintURI = [](test::jtx::Account const& account, std::string const& uri) {
|
||||
Json::Value jv;
|
||||
jv[jss::TransactionType] = jss::URITokenMint;
|
||||
jv[jss::Flags] = tfBurnable;
|
||||
jv[jss::Account] = account.human();
|
||||
jv[sfURI.jsonName] = strHex(uri);
|
||||
return jv;
|
||||
};
|
||||
env(mintURI(alice, uri), sig(alie));
|
||||
env.close();
|
||||
|
||||
auto tokenid = [](jtx::Account const& account, std::string const& uri) {
|
||||
auto const k = keylet::uritoken(account, Blob(uri.begin(), uri.end()));
|
||||
return k.key;
|
||||
};
|
||||
auto const tid = tokenid(alice, uri);
|
||||
std::string const hexid{strHex(tid)};
|
||||
|
||||
// Sell URIToken
|
||||
auto sellURI = [](test::jtx::Account const& account, std::string const& id, STAmount const& amount) {
|
||||
Json::Value jv;
|
||||
jv[jss::TransactionType] = jss::URITokenCreateSellOffer;
|
||||
jv[jss::Account] = account.human();
|
||||
jv[jss::Amount] = amount.getJson(JsonOptions::none);
|
||||
jv[sfURITokenID.jsonName] = id;
|
||||
return jv;
|
||||
};
|
||||
env(sellURI(alice, hexid, XRP(10)), sig(alie));
|
||||
env.close();
|
||||
|
||||
// Buy URIToken
|
||||
auto buyURI = [](test::jtx::Account const& account, std::string const& id, STAmount const& amount) {
|
||||
Json::Value jv;
|
||||
jv[jss::TransactionType] = jss::URITokenBuy;
|
||||
jv[jss::Account] = account.human();
|
||||
jv[jss::Amount] = amount.getJson(JsonOptions::none);
|
||||
jv[sfURITokenID.jsonName] = id;
|
||||
return jv;
|
||||
};
|
||||
env(buyURI(gw, hexid, XRP(10)));
|
||||
env.close();
|
||||
|
||||
// Sell URIToken
|
||||
env(sellURI(gw, hexid, XRP(10)));
|
||||
env.close();
|
||||
|
||||
// Clear URIToken
|
||||
auto cancelURI = [](test::jtx::Account const& account, std::string const& id) {
|
||||
Json::Value jv;
|
||||
jv[jss::TransactionType] = jss::URITokenCancelSellOffer;
|
||||
jv[jss::Account] = account.human();
|
||||
jv[sfURITokenID.jsonName] = id;
|
||||
return jv;
|
||||
};
|
||||
env(cancelURI(gw, hexid));
|
||||
env.close();
|
||||
|
||||
// Burn URIToken
|
||||
auto burnURI = [](test::jtx::Account const& account, std::string const& id) {
|
||||
Json::Value jv;
|
||||
jv[jss::TransactionType] = jss::URITokenBurn;
|
||||
jv[jss::Account] = account.human();
|
||||
jv[sfURITokenID.jsonName] = id;
|
||||
return jv;
|
||||
};
|
||||
env(burnURI(gw, hexid));
|
||||
env.close();
|
||||
}
|
||||
|
||||
// Hook
|
||||
{
|
||||
|
||||
// Create Hook
|
||||
auto createHook = [](test::jtx::Account const& account) {
|
||||
std::string const createHookHex = "0061736D0100000001130360037F7F7E017E60027F7F017F60017F017E02170203656E7606616363657074000003656E76025F670001030201020503010002062B077F01418088040B7F004180080B7F004180080B7F004180080B7F00418088040B7F0041000B7F0041010B07080104686F6F6B00020AB5800001B1800001017F230041106B220124002001200036020C410022002000420010001A41012200200010011A200141106A240042000B";
|
||||
Json::Value jv = ripple::test::jtx::hook(account, {{hso(createHookHex)}}, 0);
|
||||
return jv;
|
||||
};
|
||||
env(createHook(alice), HSFEE, sig(alie));
|
||||
env.close();
|
||||
|
||||
// Update Hook - Binary
|
||||
auto updateHook = [](test::jtx::Account const& account) {
|
||||
std::string const updateHookHex = "0061736D0100000001130360037F7F7E017E60027F7F017F60017F017E02170203656E7606616363657074000003656E76025F670001030201020503010002062B077F01418088040B7F004180080B7F004180080B7F004180080B7F00418088040B7F0041000B7F0041010B07080104686F6F6B00020AB5800001B1800001017F230041106B220124002001200036020C410022002000420010001A41012200200010011A200141106A240042000B";
|
||||
Json::Value jhv = hso(updateHookHex);
|
||||
jhv[jss::Flags] = hsfOVERRIDE;
|
||||
Json::Value jv = ripple::test::jtx::hook(account, {{jhv}}, hsfOVERRIDE);
|
||||
return jv;
|
||||
};
|
||||
env(updateHook(alice), HSFEE, sig(alie));
|
||||
env.close();
|
||||
|
||||
// Install Hook - Hash
|
||||
auto hh = [&](jtx::Env const& env, jtx::Account const& account) -> uint256 {
|
||||
auto const hook = env.le(keylet::hook(account.id()));
|
||||
if (hook) {
|
||||
auto const& hooks = hook->getFieldArray(sfHooks);
|
||||
if (hooks.size() > 0) {
|
||||
return hooks[0].getFieldH256(sfHookHash);
|
||||
}
|
||||
}
|
||||
return uint256{beast::zero};
|
||||
};
|
||||
auto installHook = [](test::jtx::Account const& account, uint256 const& hookHash) {
|
||||
Json::Value jhv;
|
||||
jhv[jss::Flags] = hsfOVERRIDE;
|
||||
jhv[jss::HookOn] = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
jhv[jss::HookNamespace] = to_string(uint256{beast::zero});
|
||||
jhv[jss::HookHash] = to_string(hookHash);
|
||||
Json::Value jv = ripple::test::jtx::hook(account, {{jhv}}, hsfOVERRIDE);
|
||||
return jv;
|
||||
};
|
||||
uint256 const hid = hh(env, alice);
|
||||
env(installHook(alice, hid), HSFEE, sig(alie));
|
||||
env.close();
|
||||
|
||||
// Delete Hook
|
||||
auto deleteHook = [](test::jtx::Account const& account) {
|
||||
Json::Value jv = ripple::test::jtx::hook(account, {{hso_delete()}}, hsfOVERRIDE);
|
||||
return jv;
|
||||
};
|
||||
env(deleteHook(alice), HSFEE, sig(alie));
|
||||
env.close();
|
||||
}
|
||||
|
||||
// Setup is done. Look at the transactions returned by account_tx.
|
||||
Json::Value params;
|
||||
params[jss::account] = alice.human();
|
||||
params[jss::ledger_index_min] = -1;
|
||||
@@ -421,29 +557,39 @@ class AccountTx_test : public beast::unit_test::suite
|
||||
// Do a sanity check on each returned transaction. They should
|
||||
// be returned in the reverse order of application to the ledger.
|
||||
static const NodeSanity sanity[]{
|
||||
// txType, created, deleted, modified
|
||||
{0, jss::DepositPreauth, {jss::DepositPreauth}, {jss::Ticket}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{1, jss::TicketCreate, {jss::Ticket}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{2, jss::CheckCancel, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{3, jss::CheckCash, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{4, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{5, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{6, jss::PaymentChannelClaim, {}, {jss::PayChannel}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{7, jss::PaymentChannelFund, {}, {}, {jss::AccountRoot, jss::PayChannel}},
|
||||
{8, jss::PaymentChannelCreate, {jss::PayChannel}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{9, jss::EscrowCancel, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{10, jss::EscrowFinish, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{11, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{12, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{13, jss::SignerListSet, {jss::SignerList}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{14, jss::OfferCancel, {}, {jss::Offer, jss::DirectoryNode}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{15, jss::OfferCreate, {jss::Offer, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{16, jss::TrustSet, {jss::RippleState, jss::DirectoryNode, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::AccountRoot}},
|
||||
{17, jss::SetRegularKey, {}, {}, {jss::AccountRoot}},
|
||||
{18, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
|
||||
{19, jss::AccountSet, {}, {}, {jss::AccountRoot}},
|
||||
{20, jss::AccountSet, {}, {}, {jss::AccountRoot}},
|
||||
{21, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
|
||||
// txType, created, deleted, modified
|
||||
{0, jss::SetHook, {}, {jss::Hook, jss::HookDefinition}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{1, jss::SetHook, {}, {}, {jss::AccountRoot, jss::Hook}},
|
||||
{2, jss::SetHook, {}, {}, {jss::AccountRoot, jss::Hook}},
|
||||
{3, jss::SetHook, {jss::Hook, jss::HookDefinition}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{4, jss::URITokenBurn, {}, {jss::URIToken}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{5, jss::URITokenCancelSellOffer, {}, {}, {jss::AccountRoot, jss::URIToken}},
|
||||
{6, jss::URITokenCreateSellOffer, {}, {}, {jss::AccountRoot, jss::URIToken}},
|
||||
{7, jss::URITokenBuy, {}, {}, {jss::AccountRoot, jss::DirectoryNode, jss::URIToken}},
|
||||
{8, jss::URITokenCreateSellOffer, {}, {}, {jss::AccountRoot, jss::URIToken}},
|
||||
{9, jss::URITokenMint, {jss::URIToken}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{10, jss::DepositPreauth, {jss::DepositPreauth}, {jss::Ticket}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{11, jss::TicketCreate, {jss::Ticket}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{12, jss::CheckCancel, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{13, jss::CheckCash, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{14, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{15, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{16, jss::PaymentChannelClaim, {}, {jss::PayChannel}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{17, jss::PaymentChannelFund, {}, {}, {jss::AccountRoot, jss::PayChannel}},
|
||||
{18, jss::PaymentChannelCreate, {jss::PayChannel}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
|
||||
{19, jss::EscrowCancel, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{20, jss::EscrowFinish, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{21, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{22, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{23, jss::SignerListSet, {jss::SignerList}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{24, jss::OfferCancel, {}, {jss::Offer, jss::DirectoryNode}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{25, jss::OfferCreate, {jss::Offer, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::DirectoryNode}},
|
||||
{26, jss::TrustSet, {jss::RippleState, jss::DirectoryNode, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::AccountRoot}},
|
||||
{27, jss::SetRegularKey, {}, {}, {jss::AccountRoot}},
|
||||
{28, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
|
||||
{29, jss::AccountSet, {}, {}, {jss::AccountRoot}},
|
||||
{30, jss::AccountSet, {}, {}, {jss::AccountRoot}},
|
||||
{31, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -376,6 +376,17 @@ public:
|
||||
env(jv);
|
||||
}
|
||||
|
||||
{
|
||||
std::string const createCodeHex = "0061736D01000000011B0460027F7F017F60047F7F7F7F017E60037F7F7E017E60017F017E02270303656E76025F67000003656E760973746174655F736574000103656E76066163636570740002030201030503010002062B077F01419088040B7F004180080B7F00418A080B7F004180080B7F00419088040B7F0041000B7F0041010B07080104686F6F6B00030AE7800001E3800002017F017E230041106B220124002001200036020C41012200200010001A2001418008280000360208200141046A410022002F0088083B010020012000280084083602004100200020014106200141086A4104100110022102200141106A240020020B0B1001004180080B096B65790076616C7565";
|
||||
std::string ns_str = "CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE";
|
||||
Json::Value jv = ripple::test::jtx::hook(Account{"bob3"}, {{hso(createCodeHex)}}, 0);
|
||||
jv[jss::Hooks][0U][jss::Hook][jss::HookNamespace] = ns_str;
|
||||
env(jv, fee(100'000'000));
|
||||
env.close();
|
||||
env(pay(Account{"bob2"}, Account{"bob3"}, XRP(1)), fee(XRP(1)));
|
||||
env.close();
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::TransactionType] = jss::PaymentChannelCreate;
|
||||
@@ -423,7 +434,7 @@ public:
|
||||
|
||||
{ // jvParams[jss::type] = "directory";
|
||||
auto const jrr = makeRequest(jss::directory);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 9));
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 10));
|
||||
for (auto const& j : jrr[jss::state])
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::DirectoryNode);
|
||||
}
|
||||
@@ -477,6 +488,27 @@ public:
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::Escrow);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "hook";
|
||||
auto const jrr = makeRequest(jss::hook);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
for (auto const& j : jrr[jss::state])
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::Hook);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "hook_definition";
|
||||
auto const jrr = makeRequest(jss::hook_definition);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
for (auto const& j : jrr[jss::state])
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::HookDefinition);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "hook_state";
|
||||
auto const jrr = makeRequest(jss::hook_state);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
for (auto const& j : jrr[jss::state])
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::HookState);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "payment_channel";
|
||||
auto const jrr = makeRequest(jss::payment_channel);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user