Compare commits

...

8 Commits

Author SHA1 Message Date
Denis Angell
000a060409 dump 2023-11-28 11:09:04 +01:00
Denis Angell
1b3aa7c051 dump 2023-11-25 00:01:14 +01:00
Denis Angell
5c144b6ce6 dump 2023-11-23 11:28:40 +01:00
Denis Angell
47128272be dump 2023-11-21 12:20:40 +01:00
Denis Angell
aa3a402f09 add uritoken helpers 2023-11-21 12:20:34 +01:00
Denis Angell
fac568c949 Update SetHookTSH_test.cpp 2023-11-20 11:04:51 +01:00
Denis Angell
9c35fe9067 dump 2023-11-19 19:39:22 +01:00
Denis Angell
ab54d3c6e1 add tsh tests 2023-11-19 19:38:55 +01:00
37 changed files with 6258 additions and 482 deletions

View File

@@ -703,6 +703,7 @@ if (tests)
src/test/app/AccountDelete_test.cpp
src/test/app/AccountTxPaging_test.cpp
src/test/app/AmendmentTable_test.cpp
src/test/app/BaseFee_test.cpp
src/test/app/Check_test.cpp
src/test/app/ClaimReward_test.cpp
src/test/app/CrossingLimits_test.cpp
@@ -754,6 +755,7 @@ if (tests)
src/test/app/ValidatorList_test.cpp
src/test/app/ValidatorSite_test.cpp
src/test/app/SetHook_test.cpp
src/test/app/SetHookTSH_test.cpp
src/test/app/XahauGenesis_test.cpp
src/test/app/tx/apply_test.cpp
#[===============================[
@@ -867,18 +869,24 @@ if (tests)
src/test/jtx/impl/envconfig.cpp
src/test/jtx/impl/fee.cpp
src/test/jtx/impl/flags.cpp
src/test/jtx/impl/genesis.cpp
src/test/jtx/impl/import.cpp
src/test/jtx/impl/invoice_id.cpp
src/test/jtx/impl/invoke.cpp
src/test/jtx/impl/jtx_json.cpp
src/test/jtx/impl/last_ledger_sequence.cpp
src/test/jtx/impl/memo.cpp
src/test/jtx/impl/multisign.cpp
src/test/jtx/impl/network.cpp
src/test/jtx/impl/offer.cpp
src/test/jtx/impl/owners.cpp
src/test/jtx/impl/paths.cpp
src/test/jtx/impl/pay.cpp
src/test/jtx/impl/paychan.cpp
src/test/jtx/impl/quality2.cpp
src/test/jtx/impl/rate.cpp
src/test/jtx/impl/regkey.cpp
src/test/jtx/impl/reward.cpp
src/test/jtx/impl/sendmax.cpp
src/test/jtx/impl/seq.cpp
src/test/jtx/impl/sig.cpp
@@ -888,6 +896,7 @@ if (tests)
src/test/jtx/impl/trust.cpp
src/test/jtx/impl/txflags.cpp
src/test/jtx/impl/utility.cpp
src/test/jtx/impl/uritoken.cpp
#[===============================[
test sources:

28
hook/tsh.c Normal file
View File

@@ -0,0 +1,28 @@
#include "hookapi.h"
int64_t hook(uint32_t reserved) {
TRACESTR("tsh.c: Start.");
switch (reserved)
{
case 0:
TRACESTR("tsh.c: Strong. Execute BEFORE transaction is applied to ledger");
break;
case 1:
TRACESTR("tsh.c: Weak. Execute AFTER transaction is applied to ledger");
break;
case 2:
TRACESTR("tsh.c: Weak Again. Execute AFTER transaction is applied to ledger");
break;
default:
break;
}
TRACESTR("tsh.c: End.");
uint8_t r_buf[4];
UINT32_TO_BUF(r_buf, reserved);
accept(SBUF(r_buf), __LINE__);
_g(1,1);
// unreachable
return 0;
}

1
hook/tsh.h Normal file

File diff suppressed because one or more lines are too long

19
hook/xahau.py Normal file
View File

@@ -0,0 +1,19 @@
import binascii
name: str = "tsh"
with open(f"build/{name}.wasm", "rb") as file:
wasm = file.read()
data = wasm.hex().upper()
# print(data)
# Convert hexadecimal data to bytes
binary_data = binascii.unhexlify(data)
# Generate C array
c_array = ', '.join([f"0x{b:02x}U" for b in binary_data])
with open(f"hook/{name}.h", "w") as file:
file.write(f'static const std::vector<uint8_t> {name.capitalize()}Hook = {"{"}')
file.write(c_array)
file.write("};\n")

View File

@@ -47,7 +47,7 @@ using namespace ripple;
static const std::map<uint16_t, uint8_t> TSHAllowances = {
{ttPAYMENT, tshROLLBACK},
{ttESCROW_CREATE, tshROLLBACK},
{ttESCROW_FINISH, tshROLLBACK},
{ttESCROW_FINISH, tshCOLLECT},
{ttACCOUNT_SET, tshNONE},
{ttESCROW_CANCEL, tshCOLLECT},
{ttREGULAR_KEY_SET, tshROLLBACK},
@@ -59,7 +59,7 @@ static const std::map<uint16_t, uint8_t> TSHAllowances = {
{ttPAYCHAN_FUND, tshCOLLECT},
{ttPAYCHAN_CLAIM, tshCOLLECT},
{ttCHECK_CREATE, tshROLLBACK},
{ttCHECK_CASH, tshROLLBACK},
{ttCHECK_CASH, tshCOLLECT},
{ttCHECK_CANCEL, tshCOLLECT},
{ttDEPOSIT_PREAUTH, tshROLLBACK},
{ttTRUST_SET, tshCOLLECT},
@@ -72,11 +72,11 @@ static const std::map<uint16_t, uint8_t> TSHAllowances = {
{ttNFTOKEN_ACCEPT_OFFER, tshROLLBACK},
{ttCLAIM_REWARD, tshROLLBACK},
{ttINVOKE, tshROLLBACK},
{ttURITOKEN_MINT, tshNONE},
{ttURITOKEN_BURN, tshROLLBACK},
{ttURITOKEN_MINT, tshCOLLECT},
{ttURITOKEN_BURN, tshCOLLECT},
{ttURITOKEN_BUY, tshROLLBACK},
{ttURITOKEN_CREATE_SELL_OFFER, tshROLLBACK},
{ttURITOKEN_CANCEL_SELL_OFFER, tshNONE},
{ttURITOKEN_CANCEL_SELL_OFFER, tshCOLLECT},
{ttIMPORT, tshROLLBACK},
{ttGENESIS_MINT, tshCOLLECT},
};

View File

@@ -88,6 +88,8 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
if (!ut || ut->getFieldU16(sfLedgerEntryType) != ltURI_TOKEN)
return {};
// ut->getFlags() & lsfBurnable
auto const owner = ut->getAccountID(sfOwner);
auto const issuer = ut->getAccountID(sfIssuer);
@@ -126,7 +128,7 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
auto const owner = ut->getAccountID(sfOwner);
if (owner != tx.getAccountID(sfAccount))
if (*otxnAcc != owner)
{
// current owner is a strong TSH
ADD_TSH(owner, canRollback);
@@ -134,12 +136,37 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
// issuer is also a strong TSH if the burnable flag is set
auto const issuer = ut->getAccountID(sfIssuer);
if (issuer != owner)
if (*otxnAcc != issuer)
ADD_TSH(issuer, ut->getFlags() & lsfBurnable);
break;
}
case ttURITOKEN_CANCEL_SELL_OFFER: {
Keylet const id{ltURI_TOKEN, tx.getFieldH256(sfURITokenID)};
if (!rv.exists(id))
return {};
auto const ut = rv.read(id);
if (!ut || ut->getFieldU16(sfLedgerEntryType) != ltURI_TOKEN)
return {};
// destination is weak tsh
if (ut->isFieldPresent(sfDestination))
ADD_TSH(ut->getAccountID(sfDestination), canRollback);
break;
}
case ttURITOKEN_MINT: {
// destination is a weak tsh
if (tx.isFieldPresent(sfDestination))
ADD_TSH(tx.getAccountID(sfDestination), canRollback);
break;
}
case ttURITOKEN_CREATE_SELL_OFFER: {
Keylet const id{ltURI_TOKEN, tx.getFieldH256(sfURITokenID)};
if (!rv.exists(id))
@@ -250,8 +277,6 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
}
// self transactions
case ttURITOKEN_MINT:
case ttURITOKEN_CANCEL_SELL_OFFER:
case ttACCOUNT_SET:
case ttOFFER_CANCEL:
case ttTICKET_CREATE:
@@ -300,18 +325,37 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
case ttESCROW_CANCEL:
case ttESCROW_FINISH: {
if (!tx.isFieldPresent(sfOwner) ||
!tx.isFieldPresent(sfOfferSequence))
if (!tx.isFieldPresent(sfOwner))
return {};
auto escrow = rv.read(keylet::escrow(
tx.getAccountID(sfOwner), tx.getFieldU32(sfOfferSequence)));
if (!tx.isFieldPresent(sfOfferSequence) &&
!tx.isFieldPresent(sfEscrowID))
return {};
std::optional<uint256> escrowID = tx[~sfEscrowID];
std::optional<std::uint32_t> offerSeq = tx[~sfOfferSequence];
Keylet k = escrowID
? Keylet(ltESCROW, *escrowID)
: keylet::escrow(tx.getAccountID(sfOwner), *offerSeq);
auto escrow = rv.read(k);
if (!escrow)
return {};
ADD_TSH(escrow->getAccountID(sfAccount), true);
ADD_TSH(escrow->getAccountID(sfDestination), canRollback);
// ADD_TSH(escrow->getAccountID(sfAccount), true);
// ADD_TSH(escrow->getAccountID(sfDestination), canRollback);
if (otxnAcc == escrow->getAccountID(sfAccount))
{
// ADD_TSH(escrow->getAccountID(sfAccount), true);
ADD_TSH(escrow->getAccountID(sfDestination), canRollback);
}
if (otxnAcc == escrow->getAccountID(sfDestination))
{
// ADD_TSH(escrow->getAccountID(sfDestination), true);
ADD_TSH(escrow->getAccountID(sfAccount), canRollback);
}
break;
}
@@ -324,8 +368,20 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
if (!chan)
return {};
ADD_TSH(chan->getAccountID(sfAccount), true);
ADD_TSH(chan->getAccountID(sfDestination), canRollback);
// ADD_TSH(chan->getAccountID(sfAccount), true);
// ADD_TSH(chan->getAccountID(sfDestination), canRollback);
if (otxnAcc == chan->getAccountID(sfAccount))
{
// ADD_TSH(escrow->getAccountID(sfAccount), true);
ADD_TSH(chan->getAccountID(sfDestination), canRollback);
}
if (otxnAcc == chan->getAccountID(sfDestination))
{
// ADD_TSH(escrow->getAccountID(sfDestination), true);
ADD_TSH(chan->getAccountID(sfAccount), canRollback);
}
break;
}
@@ -337,9 +393,17 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
auto check = rv.read(Keylet{ltCHECK, tx.getFieldH256(sfCheckID)});
if (!check)
return {};
ADD_TSH(check->getAccountID(sfAccount), true);
ADD_TSH(check->getAccountID(sfDestination), canRollback);
if (otxnAcc == check->getAccountID(sfAccount))
{
// ADD_TSH(check->getAccountID(sfAccount), true);
ADD_TSH(check->getAccountID(sfDestination), canRollback);
}
if (otxnAcc == check->getAccountID(sfDestination))
{
// ADD_TSH(check->getAccountID(sfDestination), true);
ADD_TSH(check->getAccountID(sfAccount), canRollback);
}
break;
}

View File

@@ -818,7 +818,7 @@ Import::preflight(PreflightContext const& ctx)
<< " validation count: " << validationCount;
// check if the validation count is adequate
if (quorum >= validationCount)
if (quorum > validationCount)
{
JLOG(ctx.j.warn()) << "Import: xpop did not contain an 80% quorum for "
"the txn it purports to prove. "

View File

@@ -1415,14 +1415,16 @@ Transactor::addWeakTSHFromSandbox(detail::ApplyViewBase const& pv)
TER
Transactor::doTSH(
bool strong, // only strong iff true, only weak iff false
std::vector<std::pair<AccountID, bool>> tsh,
hook::HookStateMap& stateMap,
std::vector<hook::HookResult>& results,
std::shared_ptr<STObject const> const& provisionalMeta)
{
auto& view = ctx_.view();
std::vector<std::pair<AccountID, bool>> tsh =
hook::getTransactionalStakeHolders(ctx_.tx, view);
// std::cout << "doTSH" << "\n";
// std::vector<std::pair<AccountID, bool>> tsh =
// hook::getTransactionalStakeHolders(ctx_.tx, view);
// add the extra TSH marked out by the specific transactor (if applicable)
if (!strong)
@@ -1441,22 +1443,34 @@ Transactor::doTSH(
// obviously we will never execute OTXN account
// as a TSH because they already had first execution
if (tshAccountID == account_)
{
JLOG(j_.trace()) << "doTSH: tshAccountID == account_";
continue;
}
if (alreadyProcessed.find(tshAccountID) != alreadyProcessed.end())
{
JLOG(j_.trace()) << "doTSH: alreadyProcessed.find(tshAccountID) != alreadyProcessed.end()";
continue;
}
alreadyProcessed.emplace(tshAccountID);
// only process the relevant ones
if ((!canRollback && strong) || (canRollback && !strong))
{
JLOG(j_.trace()) << "doTSH: (!canRollback && strong) || (canRollback && !strong)";
continue;
}
auto klTshHook = keylet::hook(tshAccountID);
auto tshHook = view.read(klTshHook);
if (!(tshHook && tshHook->isFieldPresent(sfHooks)))
{
JLOG(j_.trace()) << "doTSH: !(tshHook && tshHook->isFieldPresent(sfHooks))";
continue;
}
// scoping here allows tshAcc to leave scope before
// hook execution, which is probably safer
@@ -1464,7 +1478,10 @@ Transactor::doTSH(
// check if the TSH exists and/or has any hooks
auto tshAcc = view.peek(keylet::account(tshAccountID));
if (!tshAcc)
{
JLOG(j_.trace()) << "doTSH: !tshAcc";
continue;
}
// compute and deduct fees for the TSH if applicable
XRPAmount tshFeeDrops =
@@ -1676,6 +1693,8 @@ Transactor::operator()()
// application to the ledger
std::map<AccountID, std::set<uint256>> aawMap;
std::vector<std::pair<AccountID, bool>> tsh = hook::getTransactionalStakeHolders(ctx_.tx, ctx_.view());
// Pre-application (Strong TSH) Hooks are executed here
// These TSH have the right to rollback.
// Weak TSH and callback are executed post-application.
@@ -1704,7 +1723,7 @@ Transactor::operator()()
// (who have the right to rollback the txn), any weak TSH will be
// executed after doApply has been successful (callback as well)
result = doTSH(true, stateMap, hookResults, {});
result = doTSH(true, tsh, stateMap, hookResults, {});
}
// write state if all chains executed successfully
@@ -1947,7 +1966,7 @@ Transactor::operator()()
hook::HookStateMap stateMap;
std::vector<hook::HookResult> weakResults;
doTSH(false, stateMap, weakResults, proMeta);
doTSH(false, tsh, stateMap, weakResults, proMeta);
// execute any hooks that nominated for 'again as weak'
for (auto const& [accID, hookHashes] : aawMap)

View File

@@ -188,6 +188,7 @@ protected:
TER
doTSH(
bool strong, // only do strong TSH iff true, otheriwse only weak
std::vector<std::pair<AccountID, bool>> tsh,
hook::HookStateMap& stateMap,
std::vector<hook::HookResult>& result,
std::shared_ptr<STObject const> const& provisionalMeta);

View File

@@ -145,111 +145,78 @@ private:
};
// VFALCO TODO This should only be enabled for maps.
class pair_value_compare
: public beast::detail::empty_base_optimization<Compare>
#ifdef _LIBCPP_VERSION
,
public std::binary_function<value_type, value_type, bool>
#endif
class pair_value_compare : public Compare
{
public:
#ifndef _LIBCPP_VERSION
using first_argument = value_type;
using second_argument = value_type;
using result_type = bool;
#endif
bool
operator()(value_type const& lhs, value_type const& rhs) const
{
return this->member()(lhs.first, rhs.first);
return Compare::operator()(lhs.first, rhs.first);
}
pair_value_compare()
{
}
pair_value_compare(pair_value_compare const& other)
: beast::detail::empty_base_optimization<Compare>(other)
pair_value_compare(pair_value_compare const& other) : Compare(other)
{
}
private:
friend aged_ordered_container;
pair_value_compare(Compare const& compare)
: beast::detail::empty_base_optimization<Compare>(compare)
pair_value_compare(Compare const& compare) : Compare(compare)
{
}
};
// Compares value_type against element, used in insert_check
// VFALCO TODO hoist to remove template argument dependencies
class KeyValueCompare
: public beast::detail::empty_base_optimization<Compare>
#ifdef _LIBCPP_VERSION
,
public std::binary_function<Key, element, bool>
#endif
class KeyValueCompare : public Compare
{
public:
#ifndef _LIBCPP_VERSION
using first_argument = Key;
using second_argument = element;
using result_type = bool;
#endif
KeyValueCompare() = default;
KeyValueCompare(Compare const& compare)
: beast::detail::empty_base_optimization<Compare>(compare)
KeyValueCompare(Compare const& compare) : Compare(compare)
{
}
// VFALCO NOTE WE might want only to enable these overloads
// if Compare has is_transparent
#if 0
template <class K>
bool operator() (K const& k, element const& e) const
{
return this->member() (k, extract (e.value));
}
template <class K>
bool operator() (element const& e, K const& k) const
{
return this->member() (extract (e.value), k);
}
#endif
bool
operator()(Key const& k, element const& e) const
{
return this->member()(k, extract(e.value));
return Compare::operator()(k, extract(e.value));
}
bool
operator()(element const& e, Key const& k) const
{
return this->member()(extract(e.value), k);
return Compare::operator()(extract(e.value), k);
}
bool
operator()(element const& x, element const& y) const
{
return this->member()(extract(x.value), extract(y.value));
return Compare::operator()(extract(x.value), extract(y.value));
}
Compare&
compare()
{
return beast::detail::empty_base_optimization<Compare>::member();
return *this;
}
Compare const&
compare() const
{
return beast::detail::empty_base_optimization<Compare>::member();
return *this;
}
};

View File

@@ -148,115 +148,84 @@ private:
};
// VFALCO TODO hoist to remove template argument dependencies
class ValueHash : private beast::detail::empty_base_optimization<Hash>
#ifdef _LIBCPP_VERSION
,
public std::unary_function<element, std::size_t>
#endif
class ValueHash : public Hash
{
public:
#ifndef _LIBCPP_VERSION
using argument_type = element;
using result_type = size_t;
#endif
ValueHash()
{
}
ValueHash(Hash const& h)
: beast::detail::empty_base_optimization<Hash>(h)
ValueHash(Hash const& h) : Hash(h)
{
}
std::size_t
operator()(element const& e) const
{
return this->member()(extract(e.value));
return Hash::operator()(extract(e.value));
}
Hash&
hash_function()
{
return this->member();
return *this;
}
Hash const&
hash_function() const
{
return this->member();
return *this;
}
};
// Compares value_type against element, used in find/insert_check
// VFALCO TODO hoist to remove template argument dependencies
class KeyValueEqual
: private beast::detail::empty_base_optimization<KeyEqual>
#ifdef _LIBCPP_VERSION
,
public std::binary_function<Key, element, bool>
#endif
class KeyValueEqual : public KeyEqual
{
public:
#ifndef _LIBCPP_VERSION
using first_argument_type = Key;
using second_argument_type = element;
using result_type = bool;
#endif
KeyValueEqual()
{
}
KeyValueEqual(KeyEqual const& keyEqual)
: beast::detail::empty_base_optimization<KeyEqual>(keyEqual)
KeyValueEqual(KeyEqual const& keyEqual) : KeyEqual(keyEqual)
{
}
// VFALCO NOTE WE might want only to enable these overloads
// if KeyEqual has is_transparent
#if 0
template <class K>
bool operator() (K const& k, element const& e) const
{
return this->member() (k, extract (e.value));
}
template <class K>
bool operator() (element const& e, K const& k) const
{
return this->member() (extract (e.value), k);
}
#endif
bool
operator()(Key const& k, element const& e) const
{
return this->member()(k, extract(e.value));
return KeyEqual::operator()(k, extract(e.value));
}
bool
operator()(element const& e, Key const& k) const
{
return this->member()(extract(e.value), k);
return KeyEqual::operator()(extract(e.value), k);
}
bool
operator()(element const& lhs, element const& rhs) const
{
return this->member()(extract(lhs.value), extract(rhs.value));
return KeyEqual::operator()(extract(lhs.value), extract(rhs.value));
}
KeyEqual&
key_eq()
{
return this->member();
return *this;
}
KeyEqual const&
key_eq() const
{
return this->member();
return *this;
}
};

View File

@@ -91,17 +91,10 @@ private:
using value_type = map_type::value_type;
struct Transform
#ifdef _LIBCPP_VERSION
: std::unary_function<
map_type::right_map::const_iterator::value_type const&,
beast::IP::Endpoint const&>
#endif
{
#ifndef _LIBCPP_VERSION
using first_argument_type =
map_type::right_map::const_iterator::value_type const&;
using result_type = beast::IP::Endpoint const&;
#endif
explicit Transform() = default;

View File

@@ -69,14 +69,9 @@ public:
public:
// Iterator transformation to extract the endpoint from Element
struct Transform
#ifdef _LIBCPP_VERSION
: public std::unary_function<Element, Endpoint>
#endif
{
#ifndef _LIBCPP_VERSION
using first_argument = Element;
using result_type = Endpoint;
#endif
explicit Transform() = default;
@@ -239,15 +234,9 @@ public:
template <bool IsConst>
struct Transform
#ifdef _LIBCPP_VERSION
: public std::
unary_function<typename lists_type::value_type, Hop<IsConst>>
#endif
{
#ifndef _LIBCPP_VERSION
using first_argument = typename lists_type::value_type;
using result_type = Hop<IsConst>;
#endif
explicit Transform() = default;

View File

@@ -398,7 +398,7 @@ SHAMapInnerNode::canonicalizeChild(
void
SHAMapInnerNode::invariants(bool is_root) const
{
unsigned count = 0;
[[maybe_unused]] unsigned count = 0;
auto [numAllocated, hashes, children] =
hashesAndChildren_.getHashesAndChildren();

View File

@@ -0,0 +1,153 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/Feature.h>
#include <ripple/protocol/jss.h>
#include <test/jtx.h>
namespace ripple {
namespace test {
class BaseFee_test : public beast::unit_test::suite
{
static uint256
tokenid(jtx::Account const& account, std::string const& uri)
{
auto const k = keylet::uritoken(account, Blob(uri.begin(), uri.end()));
return k.key;
}
std::unique_ptr<Config>
makeNetworkConfig(uint32_t networkID)
{
using namespace jtx;
return envconfig([&](std::unique_ptr<Config> cfg) {
cfg->NETWORK_ID = networkID;
Section config;
config.append(
{"reference_fee = 10",
"account_reserve = 1000000",
"owner_reserve = 200000"});
auto setup = setup_FeeVote(config);
cfg->FEES = setup;
return cfg;
});
}
void
testInvoke(FeatureBitset features)
{
testcase("invoke w/ hook params");
using namespace test::jtx;
using namespace std::literals;
test::jtx::Env env{*this, makeNetworkConfig(21337)};
auto const feeDrops = env.current()->fees().base;
auto const alice = Account("alice");
env.fund(XRP(1000), alice);
env.close();
// build tx
std::string const uri(maxTokenURILength, '?');
auto tx = uritoken::mint(alice, uri);
tx[jss::HookParameters] = Json::Value{Json::arrayValue};
tx[jss::HookParameters][0U] = Json::Value{};
tx[jss::HookParameters][0U][jss::HookParameter] = Json::Value{};
tx[jss::HookParameters][0U][jss::HookParameter]
[jss::HookParameterName] = "CAFE";
tx[jss::HookParameters][0U][jss::HookParameter]
[jss::HookParameterValue] = "DEADBEEF";
auto const jtx = env.jt(tx);
// build tx_blob
Json::Value params;
params[jss::tx_blob] = strHex(jtx.stx->getSerializer().slice());
// fee request
auto const jrr = env.rpc("json", "fee", to_string(params));
std::cout << "RESULT: " << jrr << "\n";
// verify hooks fee
auto const hooksFee = jrr[jss::result][jss::fee_hooks_feeunits];
BEAST_EXPECT(hooksFee == "16");
}
void
testURITokenFee(FeatureBitset features)
{
testcase("uritoken w/ hook params");
using namespace test::jtx;
using namespace std::literals;
test::jtx::Env env{*this, makeNetworkConfig(21337)};
auto const feeDrops = env.current()->fees().base;
auto const alice = Account("alice");
env.fund(XRP(1000), alice);
env.close();
// build tx
std::string const uri(maxTokenURILength, '?');
auto tx = uritoken::mint(alice, uri);
tx[jss::HookParameters] = Json::Value{Json::arrayValue};
tx[jss::HookParameters][0U] = Json::Value{};
tx[jss::HookParameters][0U][jss::HookParameter] = Json::Value{};
tx[jss::HookParameters][0U][jss::HookParameter]
[jss::HookParameterName] = "CAFE";
tx[jss::HookParameters][0U][jss::HookParameter]
[jss::HookParameterValue] = "DEADBEEF";
auto const jtx = env.jt(tx);
// build tx_blob
Json::Value params;
params[jss::tx_blob] = strHex(jtx.stx->getSerializer().slice());
// fee request
auto const jrr = env.rpc("json", "fee", to_string(params));
std::cout << "RESULT: " << jrr << "\n";
// verify hooks fee
auto const hooksFee = jrr[jss::result][jss::fee_hooks_feeunits];
BEAST_EXPECT(hooksFee == "16");
}
void
testWithFeats(FeatureBitset features)
{
testURITokenFee(features);
}
public:
void
run() override
{
using namespace test::jtx;
auto const sa = supported_amendments();
testWithFeats(sa);
}
};
BEAST_DEFINE_TESTSUITE(BaseFee, app, ripple);
} // namespace test
} // namespace ripple

View File

@@ -150,9 +150,7 @@ struct ClaimReward_test : public beast::unit_test::suite
.count();
// CLAIM
auto tx = claim(alice);
tx[sfIssuer.jsonName] = issuer.human();
env(tx, txResult);
env(reward::claim(alice, issuer), txResult);
env.close();
if (withClaimReward)
@@ -287,7 +285,7 @@ struct ClaimReward_test : public beast::unit_test::suite
env.fund(XRP(1000), alice);
env.close();
env(claim(alice), ter(temMALFORMED));
env(reward::claim(alice), ter(temMALFORMED));
env.close();
}

View File

@@ -21,7 +21,7 @@ public:
static std::string unl_seq_2_1;
};
std::string ImportTCAccountSet::min = R"json({
inline inline std::string ImportTCAccountSet::min = R"json({
"ledger": {
"acroot": "97A33800660C87FB79EA1E7F998B6E0F864FBB8C36E1828D5F44E5AE2C7B0832",
"close": 742337421,
@@ -62,7 +62,7 @@ std::string ImportTCAccountSet::min = R"json({
}
}
})json";
std::string ImportTCAccountSet::max = R"json({
inline std::string ImportTCAccountSet::max = R"json({
"ledger": {
"acroot": "AD9748D06C5CFD7E48271985A7CAAE3CA4E4E8791AAA2CD0D4B72150808A2288",
"close": 748341281,
@@ -103,7 +103,7 @@ std::string ImportTCAccountSet::max = R"json({
}
}
})json";
std::string ImportTCAccountSet::w_seed = R"json({
inline std::string ImportTCAccountSet::w_seed = R"json({
"ledger": {
"acroot": "8D612AAAEA2C875978527851BB0727CE64B21D792E91B791FEC769C01410B405",
"close": 743212280,
@@ -196,7 +196,7 @@ std::string ImportTCAccountSet::w_seed = R"json({
}
}
})json";
std::string ImportTCAccountSet::w_regular_key = R"json({
inline std::string ImportTCAccountSet::w_regular_key = R"json({
"ledger": {
"acroot": "9F5FE56CF5184831882F49386A0BC4458D787A28BD7CE8A1643D8F906647ED85",
"close": 743211212,
@@ -237,7 +237,7 @@ std::string ImportTCAccountSet::w_regular_key = R"json({
}
}
})json";
std::string ImportTCAccountSet::w_signers = R"json({
inline std::string ImportTCAccountSet::w_signers = R"json({
"ledger": {
"acroot": "F2AA543F4F1D53ECE1B6DC8BAE3C97E201F9403E324C41AB377A0F21BF78A987",
"close": 742912362,
@@ -278,7 +278,7 @@ std::string ImportTCAccountSet::w_signers = R"json({
}
}
})json";
std::string ImportTCAccountSet::w_flags = R"json({
inline std::string ImportTCAccountSet::w_flags = R"json({
"ledger": {
"acroot": "54096307B907CB442BD9C1DB57EB2171927E157714462BB72B4C2FEBD25BF73A",
"close": 742411861,
@@ -319,7 +319,7 @@ std::string ImportTCAccountSet::w_flags = R"json({
}
}
})json";
std::string ImportTCAccountSet::unl_seq_1_1 = R"json({
inline std::string ImportTCAccountSet::unl_seq_1_1 = R"json({
"ledger": {
"acroot": "A0A93026933F344C144231B6AA775A19F37CB1D11D7BC84D79934E0348EF7CF4",
"close": 748090601,
@@ -421,7 +421,7 @@ std::string ImportTCAccountSet::unl_seq_1_1 = R"json({
}
}
})json";
std::string ImportTCAccountSet::unl_seq_1_2 = R"json({
inline std::string ImportTCAccountSet::unl_seq_1_2 = R"json({
"ledger": {
"acroot": "BCD3709EE7C290CE7766CB0C13E7CEDDE97B9C4452DF995ED22D6B86B85C5F98",
"close": 748090611,
@@ -462,7 +462,7 @@ std::string ImportTCAccountSet::unl_seq_1_2 = R"json({
}
}
})json";
std::string ImportTCAccountSet::unl_seq_2_1 = R"json({
inline std::string ImportTCAccountSet::unl_seq_2_1 = R"json({
"ledger": {
"acroot": "50ED9A8EE14A78437A063A529D6DFBB821B39A75D429967DE5A38EAEE09759F1",
"close": 748091081,
@@ -518,7 +518,7 @@ public:
static std::string w_signers_empty;
};
std::string ImportTCSetRegularKey::w_seed_bad_fee = R"json({
inline std::string ImportTCSetRegularKey::w_seed_bad_fee = R"json({
"ledger": {
"acroot": "64F75A08037D9F8ED8A103893401EB2AD726E7D6AAC3EAA249005916A9354892",
"close": 743008501,
@@ -579,7 +579,7 @@ std::string ImportTCSetRegularKey::w_seed_bad_fee = R"json({
}
}
})json";
std::string ImportTCSetRegularKey::w_seed_zero = R"json({
inline std::string ImportTCSetRegularKey::w_seed_zero = R"json({
"ledger": {
"acroot": "64F75A08037D9F8ED8A103893401EB2AD726E7D6AAC3EAA249005916A9354892",
"close": 743008501,
@@ -640,7 +640,7 @@ std::string ImportTCSetRegularKey::w_seed_zero = R"json({
}
}
})json";
std::string ImportTCSetRegularKey::w_seed = R"json({
inline std::string ImportTCSetRegularKey::w_seed = R"json({
"ledger": {
"acroot": "1C4B7BA1F41E8CE7990AAAE112E173837F30D0B2F54B75E43BD3713C75F39518",
"close": 743235971,
@@ -681,7 +681,7 @@ std::string ImportTCSetRegularKey::w_seed = R"json({
}
}
})json";
std::string ImportTCSetRegularKey::w_seed_empty = R"json({
inline std::string ImportTCSetRegularKey::w_seed_empty = R"json({
"ledger": {
"acroot": "84E97969C15407AF9ADFA4E54086F4AB490557950C198B51B6AD81A4EEC1ED01",
"close": 742952510,
@@ -722,7 +722,7 @@ std::string ImportTCSetRegularKey::w_seed_empty = R"json({
}
}
})json";
std::string ImportTCSetRegularKey::w_regular_key_empty = R"json({
inline std::string ImportTCSetRegularKey::w_regular_key_empty = R"json({
"ledger": {
"acroot": "D9EE30E9023D8AA0C6313B3B333DE18AA78B44EB47CB38D66D5F284C4B25DD23",
"close": 742955742,
@@ -763,7 +763,7 @@ std::string ImportTCSetRegularKey::w_regular_key_empty = R"json({
}
}
})json";
std::string ImportTCSetRegularKey::w_signers_empty = R"json({
inline std::string ImportTCSetRegularKey::w_signers_empty = R"json({
"ledger": {
"acroot": "7F6338E21FF1E6AE92C5C60358DE3ECC08B12AED298093DFC1DA6966FDD8D196",
"close": 742956561,
@@ -804,7 +804,7 @@ std::string ImportTCSetRegularKey::w_signers_empty = R"json({
}
}
})json";
std::string ImportTCSetRegularKey::w_regular_key = R"json({
inline std::string ImportTCSetRegularKey::w_regular_key = R"json({
"ledger": {
"acroot": "DB4ABE881FD4559A2332E0F52A77C88F5451E1DB437628C059547578E7329DEE",
"close": 742942750,
@@ -845,7 +845,7 @@ std::string ImportTCSetRegularKey::w_regular_key = R"json({
}
}
})json";
std::string ImportTCSetRegularKey::w_signers = R"json({
inline std::string ImportTCSetRegularKey::w_signers = R"json({
"ledger": {
"acroot": "286B589185ABF9432405869E0FBCA96CAA64F57757206951A1596521A5BBAA02",
"close": 742945892,
@@ -899,7 +899,7 @@ public:
static std::string w_signers_empty;
};
std::string ImportTCSignersListSet::w_seed_bad_fee = R"json({
inline std::string ImportTCSignersListSet::w_seed_bad_fee = R"json({
"ledger": {
"acroot": "64F75A08037D9F8ED8A103893401EB2AD726E7D6AAC3EAA249005916A9354892",
"close": 743008501,
@@ -960,7 +960,7 @@ std::string ImportTCSignersListSet::w_seed_bad_fee = R"json({
}
}
})json";
std::string ImportTCSignersListSet::w_seed = R"json({
inline std::string ImportTCSignersListSet::w_seed = R"json({
"ledger": {
"acroot": "8112FF5F3FEEA34894A16CCCD64A24D552521F2E699780A587A9E6F5F5117CE5",
"close": 743008510,
@@ -1001,7 +1001,7 @@ std::string ImportTCSignersListSet::w_seed = R"json({
}
}
})json";
std::string ImportTCSignersListSet::w_regular_key = R"json({
inline std::string ImportTCSignersListSet::w_regular_key = R"json({
"ledger": {
"acroot": "2A25CA219781A3144C72FD5FB6EB62763214E050050DA6176624A046C51EECBD",
"close": 743015350,
@@ -1042,7 +1042,7 @@ std::string ImportTCSignersListSet::w_regular_key = R"json({
}
}
})json";
std::string ImportTCSignersListSet::w_signers = R"json({
inline std::string ImportTCSignersListSet::w_signers = R"json({
"ledger": {
"acroot": "BC35E65B52724CF258BDAC8B8E0D3B9CA0F012F5B243F6AAD1B671EDABD5188E",
"close": 745594953,
@@ -1083,7 +1083,7 @@ std::string ImportTCSignersListSet::w_signers = R"json({
}
}
})json";
std::string ImportTCSignersListSet::w_seed_empty = R"json({
inline std::string ImportTCSignersListSet::w_seed_empty = R"json({
"ledger": {
"acroot": "ECCAFDE52A6D5F1E36EB82EAA5247FF1D8ADE51FCF1ED0842850193018A510F7",
"close": 743056482,
@@ -1124,7 +1124,7 @@ std::string ImportTCSignersListSet::w_seed_empty = R"json({
}
}
})json";
std::string ImportTCSignersListSet::w_regular_key_empty = R"json({
inline std::string ImportTCSignersListSet::w_regular_key_empty = R"json({
"ledger": {
"acroot": "E222F46D5F35C79FDA3BB98973E2024EF9F6FA7B26471CC9CEF2CE033FA0E6E7",
"close": 743169800,
@@ -1165,7 +1165,7 @@ std::string ImportTCSignersListSet::w_regular_key_empty = R"json({
}
}
})json";
std::string ImportTCSignersListSet::w_signers_empty = R"json({
inline std::string ImportTCSignersListSet::w_signers_empty = R"json({
"ledger": {
"acroot": "987438A87AD998B7D7ED04A280FB5414C76E8475D621A55FB8463F15CEEEAD49",
"close": 743172592,
@@ -1213,7 +1213,7 @@ public:
static std::string base_genesis;
};
std::string ImportTCHalving::base_genesis = R"json({
inline std::string ImportTCHalving::base_genesis = R"json({
"ledger": {
"accepted": true,
"accountState": [

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,7 @@
#include <ripple/ledger/View.h>
#include <ripple/protocol/Feature.h>
#include <string>
#include <test/csf.h>
#include <test/jtx.h>
#include <vector>
@@ -60,12 +61,12 @@ namespace test {
// * @param hasToReEnable if expect ToDisable in ledger
// * @return true if meet all three expectation
// */
// bool
// negUnlSizeTest(
// std::shared_ptr<Ledger const> const& l,
// size_t size,
// bool hasToDisable,
// bool hasToReEnable);
inline bool
negUnlSizeTest(
std::shared_ptr<Ledger const> const& l,
size_t size,
bool hasToDisable,
bool hasToReEnable);
// /**
// * Try to apply a ttUNL_MODIFY Tx, and test the apply result
@@ -164,6 +165,38 @@ createUNLRTx(
PublicKey const& importKey,
PublicKey const& valKey);
/**
* Count the number of Tx in a TxSet
*
* @param txSet the TxSet
* @return the number of Tx
*/
inline std::size_t
countTx(std::shared_ptr<SHAMap> const& txSet);
/**
* Create ttUNL_MODIFY Tx
*
* @param disabling disabling or re-enabling a validator
* @param seq current ledger seq
* @param txKey the public key of the validator
* @return the ttUNL_MODIFY Tx
*/
inline STTx
createTx(bool disabling, LedgerIndex seq, PublicKey const& txKey);
/**
* Try to apply a ttUNL_MODIFY Tx, and test the apply result
*
* @param env the test environment
* @param view the OpenView of the ledger
* @param tx the ttUNL_MODIFY Tx
* @param pass if the Tx should be applied successfully
* @return true if meet the expectation of apply result
*/
inline bool
applyAndTestResult(jtx::Env& env, OpenView& view, STTx const& tx, bool pass);
class UNLReport_test : public beast::unit_test::suite
{
// Import VL Keys
@@ -1201,6 +1234,23 @@ BEAST_DEFINE_TESTSUITE(UNLReportVoteNewValidator, consensus, ripple);
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
inline bool
negUnlSizeTest(
std::shared_ptr<Ledger const> const& l,
size_t size,
bool hasToDisable,
bool hasToReEnable)
{
bool sameSize = l->negativeUNL().size() == size;
bool sameToDisable =
(l->validatorToDisable() != std::nullopt) == hasToDisable;
bool sameToReEnable =
(l->validatorToReEnable() != std::nullopt) == hasToReEnable;
return sameSize && sameToDisable && sameToReEnable;
}
bool
applyAndTestUNLRResult(jtx::Env& env, OpenView& view, STTx const& tx, bool pass)
{
@@ -1362,5 +1412,54 @@ createUNLRTx(
return STTx(ttUNL_REPORT, fill);
}
inline STTx
createTx(bool disabling, LedgerIndex seq, PublicKey const& txKey)
{
auto fill = [&](auto& obj) {
obj.setFieldU8(sfUNLModifyDisabling, disabling ? 1 : 0);
obj.setFieldU32(sfLedgerSequence, seq);
obj.setFieldVL(sfUNLModifyValidator, txKey);
};
return STTx(ttUNL_MODIFY, fill);
}
inline std::size_t
countTx(std::shared_ptr<SHAMap> const& txSet)
{
/*uint64_t counter = 0;
if (txSet)
for (auto const& item : *txSet)
{
SerialIter sit(item.slice());
auto tx = std::make_shared<STTx
const>(SerialIter{sit.getSlice(sit.getVLDataLength())});
if (tx->getFieldU16(sfTransactionType) == ttUNL_MODIFY)
counter++;
}
*/
std::size_t count = 0;
for (auto i = txSet->begin(); i != txSet->end(); ++i)
{
// RH TODO: why does the above parse??
auto raw = i->slice();
if (raw[0] == 0x12U && raw[1] == 0 && raw[2] == 0x66U)
count++;
}
return count;
};
inline bool
applyAndTestResult(jtx::Env& env, OpenView& view, STTx const& tx, bool pass)
{
auto res = apply(env.app(), view, tx, ApplyFlags::tapNONE, env.journal);
if (pass)
return res.first == tesSUCCESS;
else
return res.first == tefFAILURE || res.first == temDISABLED;
}
} // namespace test
} // namespace ripple

View File

@@ -36,23 +36,29 @@
#include <test/jtx/deposit.h>
#include <test/jtx/fee.h>
#include <test/jtx/flags.h>
#include <test/jtx/genesis.h>
#include <test/jtx/hook.h>
#include <test/jtx/import.h>
#include <test/jtx/invoice_id.h>
#include <test/jtx/invoke.h>
#include <test/jtx/jtx_json.h>
#include <test/jtx/last_ledger_sequence.h>
#include <test/jtx/memo.h>
#include <test/jtx/multisign.h>
#include <test/jtx/network.h>
#include <test/jtx/noop.h>
#include <test/jtx/offer.h>
#include <test/jtx/owners.h>
#include <test/jtx/paths.h>
#include <test/jtx/pay.h>
#include <test/jtx/paychan.h>
#include <test/jtx/prop.h>
#include <test/jtx/quality.h>
#include <test/jtx/rate.h>
#include <test/jtx/regkey.h>
#include <test/jtx/require.h>
#include <test/jtx/requires.h>
#include <test/jtx/reward.h>
#include <test/jtx/sendmax.h>
#include <test/jtx/seq.h>
#include <test/jtx/sig.h>
@@ -64,5 +70,6 @@
#include <test/jtx/trust.h>
#include <test/jtx/txflags.h>
#include <test/jtx/utility.h>
#include <test/jtx/uritoken.h>
#endif

View File

@@ -31,6 +31,12 @@ namespace jtx {
Json::Value
acctdelete(Account const& account, Account const& dest);
void
incLgrSeqForAccDel(
jtx::Env& env,
jtx::Account const& acc,
std::uint32_t margin = 0);
} // namespace jtx
} // namespace test

40
src/test/jtx/genesis.h Normal file
View File

@@ -0,0 +1,40 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TEST_JTX_GENESIS_H_INCLUDED
#define RIPPLE_TEST_JTX_GENESIS_H_INCLUDED
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
namespace ripple {
namespace test {
namespace jtx {
/** Genesis operations. */
namespace genesis {
} // namespace genesis
} // namespace jtx
} // namespace test
} // namespace ripple
#endif

View File

@@ -18,6 +18,7 @@
//==============================================================================
#include <ripple/protocol/jss.h>
#include <test/jtx/Env.h>
#include <test/jtx/acctdelete.h>
namespace ripple {
@@ -35,6 +36,21 @@ acctdelete(jtx::Account const& account, jtx::Account const& dest)
return jv;
}
void
incLgrSeqForAccDel(
jtx::Env& env,
jtx::Account const& acc,
std::uint32_t margin)
{
int const delta = [&]() -> int {
if (env.seq(acc) + 255 > env.current()->seq())
return env.seq(acc) - env.current()->seq() + 255 - margin;
return 0;
}();
for (int i = 0; i < delta; ++i)
env.close();
}
} // namespace jtx
} // namespace test
} // namespace ripple

View File

@@ -0,0 +1,34 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/jss.h>
#include <test/jtx/genesis.h>
namespace ripple {
namespace test {
namespace jtx {
namespace genesis {
} // namespace genesis
} // namespace jtx
} // namespace test
} // namespace ripple

View File

@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/json/json_reader.h>
#include <ripple/json/json_writer.h>
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/jss.h>
#include <test/jtx/import.h>
namespace ripple {
namespace test {
namespace jtx {
namespace import {
// Import tx.
Json::Value
import(
jtx::Account const& account,
Json::Value const& xpop,
std::optional<jtx::Account> const& issuer)
{
using namespace jtx;
Json::Value jv;
std::string strJson = Json::FastWriter().write(xpop);
jv[jss::TransactionType] = jss::Import;
jv[jss::Account] = account.human();
jv[jss::Blob] = strHex(strJson);
if (issuer)
jv[sfIssuer.jsonName] = issuer->human();
return jv;
}
Json::Value
loadXpop(std::string content)
{
// If the string is empty, return an empty Json::Value
if (content.empty())
{
std::cout << "JSON string was empty"
<< "\n";
return {};
}
Json::Value jsonValue;
Json::Reader reader;
reader.parse(content, jsonValue);
return jsonValue;
}
} // namespace import
} // namespace jtx
} // namespace test
} // namespace ripple

View File

@@ -0,0 +1,100 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/jss.h>
#include <test/jtx/invoke.h>
namespace ripple {
namespace test {
namespace jtx {
namespace invoke {
// Invoke a tx.
Json::Value
invoke(
jtx::Account const& account,
std::optional<jtx::Account> const& dest)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::Invoke;
jv[jss::Account] = account.human();
if (dest)
jv[jss::Destination] = dest->human();
return jv;
}
Json::Value
invoke(
jtx::Account const& account,
std::optional<jtx::Account> const& dest,
std::optional<std::string> const& blob)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::Invoke;
jv[jss::Account] = account.human();
if (dest)
jv[jss::Destination] = dest->human();
if (blob.has_value())
jv[jss::Blob] = blob.value();
return jv;
}
std::string
makeBlob(std::vector<std::tuple<
std::optional<AccountID>,
std::optional<STAmount>,
std::optional<uint256>,
std::optional<uint256>>> entries)
{
std::string blob = "F060";
for (auto const& [acc, amt, flags, marks] : entries)
{
STObject m(sfGenesisMint);
if (acc)
m.setAccountID(sfDestination, *acc);
if (amt)
m.setFieldAmount(sfAmount, *amt);
if (flags)
m.setFieldH256(sfGovernanceFlags, *flags);
if (marks)
m.setFieldH256(sfGovernanceMarks, *marks);
Serializer s;
m.add(s);
blob += "E060" + strHex(s.getData()) + "E1";
}
blob += "F1";
return blob;
}
} // namespace invoke
} // namespace jtx
} // namespace test
} // namespace ripple

View File

@@ -0,0 +1,93 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/basics/StringUtilities.h>
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/jss.h>
#include <test/jtx/network.h>
namespace ripple {
namespace test {
namespace jtx {
namespace network {
std::unique_ptr<Config>
makeNetworkConfig(
uint32_t networkID,
std::string fee,
std::string a_res,
std::string o_res)
{
using namespace jtx;
return envconfig([&](std::unique_ptr<Config> cfg) {
cfg->NETWORK_ID = networkID;
Section config;
config.append(
{"reference_fee = " + fee,
"account_reserve = " + a_res,
"owner_reserve = " + o_res});
auto setup = setup_FeeVote(config);
cfg->FEES = setup;
return cfg;
});
}
std::unique_ptr<Config>
makeNetworkVLConfig(
uint32_t networkID,
std::string fee,
std::string a_res,
std::string o_res,
std::vector<std::string> keys)
{
using namespace jtx;
return envconfig([&](std::unique_ptr<Config> cfg) {
cfg->NETWORK_ID = networkID;
Section config;
config.append(
{"reference_fee = " + fee,
"account_reserve = " + a_res,
"owner_reserve = " + o_res});
auto setup = setup_FeeVote(config);
cfg->FEES = setup;
for (auto const& strPk : keys)
{
auto pkHex = strUnHex(strPk);
if (!pkHex)
Throw<std::runtime_error>(
"Import VL Key '" + strPk + "' was not valid hex.");
auto const pkType = publicKeyType(makeSlice(*pkHex));
if (!pkType)
Throw<std::runtime_error>(
"Import VL Key '" + strPk + "' was not a valid key type.");
cfg->IMPORT_VL_KEYS.emplace(strPk, makeSlice(*pkHex));
}
return cfg;
});
}
} // namespace network
} // namespace jtx
} // namespace test
} // namespace ripple

View File

@@ -0,0 +1,105 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/jss.h>
#include <test/jtx/paychan.h>
namespace ripple {
namespace test {
namespace jtx {
namespace paychan {
Json::Value
create(
jtx::Account const& account,
jtx::Account const& to,
STAmount const& amount,
NetClock::duration const& settleDelay,
PublicKey const& pk,
std::optional<NetClock::time_point> const& cancelAfter,
std::optional<std::uint32_t> const& dstTag)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::PaymentChannelCreate;
jv[jss::Flags] = tfUniversal;
jv[jss::Account] = account.human();
jv[jss::Destination] = to.human();
jv[jss::Amount] = amount.getJson(JsonOptions::none);
jv["SettleDelay"] = settleDelay.count();
jv["PublicKey"] = strHex(pk.slice());
if (cancelAfter)
jv["CancelAfter"] = cancelAfter->time_since_epoch().count();
if (dstTag)
jv["DestinationTag"] = *dstTag;
return jv;
}
Json::Value
fund(
jtx::Account const& account,
uint256 const& channel,
STAmount const& amount,
std::optional<NetClock::time_point> const& expiration)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::PaymentChannelFund;
jv[jss::Flags] = tfUniversal;
jv[jss::Account] = account.human();
jv["Channel"] = to_string(channel);
jv[jss::Amount] = amount.getJson(JsonOptions::none);
if (expiration)
jv["Expiration"] = expiration->time_since_epoch().count();
return jv;
}
Json::Value
claim(
jtx::Account const& account,
uint256 const& channel,
std::optional<STAmount> const& balance,
std::optional<STAmount> const& amount,
std::optional<Slice> const& signature,
std::optional<PublicKey> const& pk)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::PaymentChannelClaim;
jv[jss::Flags] = tfUniversal;
jv[jss::Account] = account.human();
jv["Channel"] = to_string(channel);
if (amount)
jv[jss::Amount] = amount->getJson(JsonOptions::none);
if (balance)
jv["Balance"] = balance->getJson(JsonOptions::none);
if (signature)
jv["Signature"] = strHex(*signature);
if (pk)
jv["PublicKey"] = strHex(pk->slice());
return jv;
}
} // namespace paychan
} // namespace jtx
} // namespace test
} // namespace ripple

View File

@@ -0,0 +1,51 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/jss.h>
#include <test/jtx/reward.h>
namespace ripple {
namespace test {
namespace jtx {
namespace reward {
// Claim a reward.
Json::Value
claim(
jtx::Account const& account,
std::optional<jtx::Account> const& issuer,
std::uint32_t flags)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::ClaimReward;
jv[jss::Account] = account.human();
if (issuer)
jv[sfIssuer.jsonName] = issuer->human();
if (flags)
jv[jss::Flags] = flags;
return jv;
}
} // namespace reward
} // namespace jtx
} // namespace test
} // namespace ripple

View File

@@ -0,0 +1,112 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/SField.h>
#include <ripple/protocol/jss.h>
#include <test/jtx/flags.h>
#include <test/jtx/uritoken.h>
namespace ripple {
namespace test {
namespace jtx {
namespace uritoken {
uint256
tokenid(jtx::Account const& account, std::string const& uri)
{
auto const k = keylet::uritoken(account, Blob(uri.begin(), uri.end()));
return k.key;
}
Json::Value
mint(jtx::Account const& account, std::string const& uri)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::URITokenMint;
jv[jss::Account] = account.human();
jv[sfURI.jsonName] = strHex(uri);
return jv;
}
void
dest::operator()(Env& env, JTx& jt) const
{
jt.jv[sfDestination.jsonName] = dest_.human();
}
void
amt::operator()(Env& env, JTx& jt) const
{
jt.jv[sfAmount.jsonName] = amt_.getJson(JsonOptions::none);
}
Json::Value
burn(jtx::Account const& account, std::string const& id)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::URITokenBurn;
jv[jss::Account] = account.human();
jv[sfURITokenID.jsonName] = id;
return jv;
}
Json::Value
sell(
jtx::Account const& account,
std::string const& id)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::URITokenCreateSellOffer;
jv[jss::Account] = account.human();
jv[sfURITokenID.jsonName] = id;
return jv;
}
Json::Value
cancel(
jtx::Account const& account,
std::string const& id)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::URITokenCancelSellOffer;
jv[jss::Account] = account.human();
jv[sfURITokenID.jsonName] = id;
return jv;
}
Json::Value
buy(jtx::Account const& account,
std::string const& id)
{
using namespace jtx;
Json::Value jv;
jv[jss::TransactionType] = jss::URITokenBuy;
jv[jss::Account] = account.human();
jv[sfURITokenID.jsonName] = id;
return jv;
}
} // namespace uritoken
} // namespace jtx
} // namespace test
} // namespace ripple

49
src/test/jtx/import.h Normal file
View File

@@ -0,0 +1,49 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TEST_JTX_IMPORT_H_INCLUDED
#define RIPPLE_TEST_JTX_IMPORT_H_INCLUDED
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
namespace ripple {
namespace test {
namespace jtx {
/** Import operations. */
namespace import {
Json::Value
import(
jtx::Account const& account,
Json::Value const& xpop,
std::optional<jtx::Account> const& issuer);
Json::Value
loadXpop(std::string content);
} // namespace import
} // namespace jtx
} // namespace test
} // namespace ripple
#endif

58
src/test/jtx/invoke.h Normal file
View File

@@ -0,0 +1,58 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TEST_JTX_INVOKE_H_INCLUDED
#define RIPPLE_TEST_JTX_INVOKE_H_INCLUDED
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
namespace ripple {
namespace test {
namespace jtx {
/** Invoke operations. */
namespace invoke {
Json::Value
invoke(
jtx::Account const& account,
std::optional<jtx::Account> const& dest);
Json::Value
invoke(
jtx::Account const& account,
std::optional<jtx::Account> const& dest,
std::optional<std::string> const& blob);
std::string
makeBlob(std::vector<std::tuple<
std::optional<AccountID>,
std::optional<STAmount>,
std::optional<uint256>,
std::optional<uint256>>> entries);
} // namespace invoke
} // namespace jtx
} // namespace test
} // namespace ripple
#endif

55
src/test/jtx/network.h Normal file
View File

@@ -0,0 +1,55 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TEST_JTX_NETWORK_H_INCLUDED
#define RIPPLE_TEST_JTX_NETWORK_H_INCLUDED
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
namespace ripple {
namespace test {
namespace jtx {
/** Network operations. */
namespace network {
std::unique_ptr<Config>
makeNetworkConfig(
uint32_t networkID,
std::string fee,
std::string a_res,
std::string o_res);
std::unique_ptr<Config>
makeNetworkVLConfig(
uint32_t networkID,
std::string fee,
std::string a_res,
std::string o_res,
std::vector<std::string> keys);
} // namespace network
} // namespace jtx
} // namespace test
} // namespace ripple
#endif

66
src/test/jtx/paychan.h Normal file
View File

@@ -0,0 +1,66 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TEST_JTX_PAYCHAN_H_INCLUDED
#define RIPPLE_TEST_JTX_PAYCHAN_H_INCLUDED
#include <ripple/json/json_value.h>
#include <ripple/protocol/STAmount.h>
#include <test/jtx/Account.h>
namespace ripple {
namespace test {
namespace jtx {
/** PayChan operations. */
namespace paychan {
Json::Value
create(
jtx::Account const& account,
jtx::Account const& to,
STAmount const& amount,
NetClock::duration const& settleDelay,
PublicKey const& pk,
std::optional<NetClock::time_point> const& cancelAfter = std::nullopt,
std::optional<std::uint32_t> const& dstTag = std::nullopt);
Json::Value
fund(
jtx::Account const& account,
uint256 const& channel,
STAmount const& amount,
std::optional<NetClock::time_point> const& expiration = std::nullopt);
Json::Value
claim(
jtx::Account const& account,
uint256 const& channel,
std::optional<STAmount> const& balance = std::nullopt,
std::optional<STAmount> const& amount = std::nullopt,
std::optional<Slice> const& signature = std::nullopt,
std::optional<PublicKey> const& pk = std::nullopt);
} // namespace paychan
} // namespace jtx
} // namespace test
} // namespace ripple
#endif

47
src/test/jtx/reward.h Normal file
View File

@@ -0,0 +1,47 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TEST_JTX_REWARD_H_INCLUDED
#define RIPPLE_TEST_JTX_REWARD_H_INCLUDED
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
namespace ripple {
namespace test {
namespace jtx {
/** ClaimReward operations. */
namespace reward {
/** Claim a reward. */
Json::Value
claim(
jtx::Account const& account,
std::optional<jtx::Account> const& issuer = std::nullopt,
std::uint32_t flags = 0);
} // namespace reward
} // namespace jtx
} // namespace test
} // namespace ripple
#endif

91
src/test/jtx/uritoken.h Normal file
View File

@@ -0,0 +1,91 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2021 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TEST_JTX_URITOKEN_H_INCLUDED
#define RIPPLE_TEST_JTX_URITOKEN_H_INCLUDED
#include <ripple/basics/strHex.h>
#include <ripple/protocol/STAmount.h>
#include <initializer_list>
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
#include <test/jtx/owners.h>
namespace ripple {
namespace test {
namespace jtx {
namespace uritoken {
uint256
tokenid(jtx::Account const& account, std::string const& uri);
Json::Value
mint(jtx::Account const& account, std::string const& uri);
/** Sets the optional Destination on an URITokenMint. */
class dest
{
private:
jtx::Account dest_;
public:
explicit dest(jtx::Account const& dest) : dest_(dest)
{
}
void
operator()(Env&, JTx& jtx) const;
};
/** Sets the optional Amount on an URITokenMint. */
class amt
{
private:
STAmount amt_;
public:
explicit amt(STAmount const& amt) : amt_(amt)
{
}
void
operator()(Env&, JTx& jtx) const;
};
Json::Value
burn(jtx::Account const& account, std::string const& id);
Json::Value
sell(jtx::Account const& account, std::string const& id);
Json::Value
cancel(jtx::Account const& account, std::string const& id);
Json::Value
buy(jtx::Account const& account, std::string const& id);
} // namespace uritoken
} // namespace jtx
} // namespace test
} // namespace ripple
#endif // RIPPLE_TEST_JTX_URITOKEN_H_INCLUDED

View File

@@ -30,22 +30,6 @@ namespace test {
class ServerDefinitions_test : public beast::unit_test::suite
{
public:
static Json::Value
loadJson(std::string content)
{
// If the string is empty, return an empty Json::Value
if (content.empty())
{
std::cout << "JSON string was empty"
<< "\n";
return {};
}
Json::Value jsonValue;
Json::Reader reader;
reader.parse(content, jsonValue);
return jsonValue;
}
void
testDefinitions(FeatureBitset features)
@@ -53,311 +37,18 @@ public:
testcase("Definitions");
using namespace test::jtx;
std::string jsonLE = R"json({
"AccountRoot" : 97,
"Amendments" : 102,
"Any" : 0,
"Check" : 67,
"Child" : 7378,
"Contract" : 99,
"DepositPreauth" : 112,
"DirectoryNode" : 100,
"EmittedTxn" : 69,
"Escrow" : 117,
"FeeSettings" : 115,
"GeneratorMap" : 103,
"Hook" : 72,
"HookDefinition" : 68,
"HookState" : 118,
"ImportVLSequence" : 73,
"Invalid" : -1,
"LedgerHashes" : 104,
"NFTokenOffer" : 55,
"NFTokenPage" : 80,
"NegativeUNL" : 78,
"Nickname" : 110,
"Offer" : 111,
"PayChannel" : 120,
"RippleState" : 114,
"SignerList" : 83,
"Ticket" : 84,
"UNLReport" : 82,
"URIToken" : 85
})json";
std::string jsonTT = R"json({
"AccountDelete" : 21,
"AccountSet" : 3,
"Amendment" : 100,
"CheckCancel" : 18,
"CheckCash" : 17,
"CheckCreate" : 16,
"ClaimReward" : 98,
"Contract" : 9,
"DepositPreauth" : 19,
"EmitFailure" : 103,
"EscrowCancel" : 4,
"EscrowCreate" : 1,
"EscrowFinish" : 2,
"Fee" : 101,
"GenesisMint" : 96,
"Import" : 97,
"Invalid" : -1,
"Invoke" : 99,
"NFTokenAcceptOffer" : 29,
"NFTokenBurn" : 26,
"NFTokenCancelOffer" : 28,
"NFTokenCreateOffer" : 27,
"NFTokenMint" : 25,
"NicknameSet" : 6,
"OfferCancel" : 8,
"OfferCreate" : 7,
"Payment" : 0,
"PaymentChannelClaim" : 15,
"PaymentChannelCreate" : 13,
"PaymentChannelFund" : 14,
"SetHook" : 22,
"SetRegularKey" : 5,
"SignerListSet" : 12,
"SpinalTap" : 11,
"TicketCreate" : 10,
"TrustSet" : 20,
"UNLModify" : 102,
"UNLReport" : 104,
"URITokenBurn" : 46,
"URITokenBuy" : 47,
"URITokenCancelSellOffer" : 49,
"URITokenCreateSellOffer" : 48,
"URITokenMint" : 45
})json";
std::string jsonTY = R"json({
"AccountID" : 8,
"Amount" : 6,
"Blob" : 7,
"Done" : -1,
"Hash128" : 4,
"Hash160" : 17,
"Hash256" : 5,
"LedgerEntry" : 10002,
"Metadata" : 10004,
"NotPresent" : 0,
"PathSet" : 18,
"STArray" : 15,
"STObject" : 14,
"Transaction" : 10001,
"UInt16" : 1,
"UInt192" : 21,
"UInt32" : 2,
"UInt384" : 22,
"UInt512" : 23,
"UInt64" : 3,
"UInt8" : 16,
"UInt96" : 20,
"Unknown" : -2,
"Validation" : 10003,
"Vector256" : 19
})json";
std::string jsonTEC = R"json({
"tecAMM_BALANCE" : 163,
"tecAMM_FAILED_BID" : 167,
"tecAMM_FAILED_DEPOSIT" : 164,
"tecAMM_FAILED_VOTE" : 168,
"tecAMM_FAILED_WITHDRAW" : 165,
"tecAMM_INVALID_TOKENS" : 166,
"tecAMM_UNFUNDED" : 162,
"tecBAD_XCHAIN_TRANSFER_ISSUE" : 171,
"tecCANT_ACCEPT_OWN_NFTOKEN_OFFER" : 158,
"tecCLAIM" : 100,
"tecCRYPTOCONDITION_ERROR" : 146,
"tecDIR_FULL" : 121,
"tecDST_TAG_NEEDED" : 143,
"tecDUPLICATE" : 149,
"tecEXPIRED" : 148,
"tecFAILED_PROCESSING" : 105,
"tecFROZEN" : 137,
"tecHAS_OBLIGATIONS" : 151,
"tecHOOK_REJECTED" : 153,
"tecINSUFFICIENT_FUNDS" : 159,
"tecINSUFFICIENT_PAYMENT" : 161,
"tecINSUFFICIENT_RESERVE" : 141,
"tecINSUFF_FEE" : 136,
"tecINSUF_RESERVE_LINE" : 122,
"tecINSUF_RESERVE_OFFER" : 123,
"tecINTERNAL" : 144,
"tecINVARIANT_FAILED" : 147,
"tecKILLED" : 150,
"tecLAST_POSSIBLE_ENTRY" : 255,
"tecMAX_SEQUENCE_REACHED" : 154,
"tecNEED_MASTER_KEY" : 142,
"tecNFTOKEN_BUY_SELL_MISMATCH" : 156,
"tecNFTOKEN_OFFER_TYPE_MISMATCH" : 157,
"tecNO_ALTERNATIVE_KEY" : 130,
"tecNO_AUTH" : 134,
"tecNO_DST" : 124,
"tecNO_DST_INSUF_NATIVE" : 125,
"tecNO_ENTRY" : 140,
"tecNO_ISSUER" : 133,
"tecNO_LINE" : 135,
"tecNO_LINE_INSUF_RESERVE" : 126,
"tecNO_LINE_REDUNDANT" : 127,
"tecNO_PERMISSION" : 139,
"tecNO_REGULAR_KEY" : 131,
"tecNO_SUITABLE_NFTOKEN_PAGE" : 155,
"tecNO_TARGET" : 138,
"tecOBJECT_NOT_FOUND" : 160,
"tecOVERSIZE" : 145,
"tecOWNERS" : 132,
"tecPATH_DRY" : 128,
"tecPATH_PARTIAL" : 101,
"tecPRECISION_LOSS" : 170,
"tecREQUIRES_FLAG" : 169,
"tecTOO_SOON" : 152,
"tecUNFUNDED" : 129,
"tecUNFUNDED_ADD" : 102,
"tecUNFUNDED_OFFER" : 103,
"tecUNFUNDED_PAYMENT" : 104,
"tecXCHAIN_ACCOUNT_CREATE_PAST" : 182,
"tecXCHAIN_ACCOUNT_CREATE_TOO_MANY" : 183,
"tecXCHAIN_BAD_CLAIM_ID" : 173,
"tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR" : 186,
"tecXCHAIN_CLAIM_NO_QUORUM" : 174,
"tecXCHAIN_CREATE_ACCOUNT_NONXRP_ISSUE" : 176,
"tecXCHAIN_INSUFF_CREATE_AMOUNT" : 181,
"tecXCHAIN_NO_CLAIM_ID" : 172,
"tecXCHAIN_NO_SIGNERS_LIST" : 179,
"tecXCHAIN_PAYMENT_FAILED" : 184,
"tecXCHAIN_PROOF_UNKNOWN_KEY" : 175,
"tecXCHAIN_REWARD_MISMATCH" : 178,
"tecXCHAIN_SELF_COMMIT" : 185,
"tecXCHAIN_SENDING_ACCOUNT_MISMATCH" : 180,
"tecXCHAIN_WRONG_CHAIN" : 177,
"tefALREADY" : -198,
"tefBAD_ADD_AUTH" : -197,
"tefBAD_AUTH" : -196,
"tefBAD_AUTH_MASTER" : -183,
"tefBAD_LEDGER" : -195,
"tefBAD_QUORUM" : -185,
"tefBAD_SIGNATURE" : -186,
"tefCREATED" : -194,
"tefEXCEPTION" : -193,
"tefFAILURE" : -199,
"tefINTERNAL" : -192,
"tefINVARIANT_FAILED" : -182,
"tefMASTER_DISABLED" : -188,
"tefMAX_LEDGER" : -187,
"tefNFTOKEN_IS_NOT_TRANSFERABLE" : -179,
"tefNOT_MULTI_SIGNING" : -184,
"tefNO_AUTH_REQUIRED" : -191,
"tefNO_TICKET" : -180,
"tefPAST_IMPORT_SEQ" : -178,
"tefPAST_IMPORT_VL_SEQ" : -177,
"tefPAST_SEQ" : -190,
"tefTOO_BIG" : -181,
"tefWRONG_PRIOR" : -189,
"telBAD_DOMAIN" : -398,
"telBAD_PATH_COUNT" : -397,
"telBAD_PUBLIC_KEY" : -396,
"telCAN_NOT_QUEUE" : -392,
"telCAN_NOT_QUEUE_BALANCE" : -391,
"telCAN_NOT_QUEUE_BLOCKED" : -389,
"telCAN_NOT_QUEUE_BLOCKS" : -390,
"telCAN_NOT_QUEUE_FEE" : -388,
"telCAN_NOT_QUEUE_FULL" : -387,
"telCAN_NOT_QUEUE_IMPORT" : -381,
"telFAILED_PROCESSING" : -395,
"telIMPORT_VL_KEY_NOT_RECOGNISED" : -382,
"telINSUF_FEE_P" : -394,
"telLOCAL_ERROR" : -399,
"telNETWORK_ID_MAKES_TX_NON_CANONICAL" : -384,
"telNON_LOCAL_EMITTED_TXN" : -383,
"telNO_DST_PARTIAL" : -393,
"telREQUIRES_NETWORK_ID" : -385,
"telWRONG_NETWORK" : -386,
"temAMM_BAD_TOKENS" : -261,
"temBAD_AMOUNT" : -298,
"temBAD_CURRENCY" : -297,
"temBAD_EXPIRATION" : -296,
"temBAD_FEE" : -295,
"temBAD_ISSUER" : -294,
"temBAD_LIMIT" : -293,
"temBAD_NFTOKEN_TRANSFER_FEE" : -262,
"temBAD_OFFER" : -292,
"temBAD_PATH" : -291,
"temBAD_PATH_LOOP" : -290,
"temBAD_QUORUM" : -271,
"temBAD_REGKEY" : -289,
"temBAD_SEND_NATIVE_LIMIT" : -288,
"temBAD_SEND_NATIVE_MAX" : -287,
"temBAD_SEND_NATIVE_NO_DIRECT" : -286,
"temBAD_SEND_NATIVE_PARTIAL" : -285,
"temBAD_SEND_NATIVE_PATHS" : -284,
"temBAD_SEQUENCE" : -283,
"temBAD_SIGNATURE" : -282,
"temBAD_SIGNER" : -272,
"temBAD_SRC_ACCOUNT" : -281,
"temBAD_TICK_SIZE" : -269,
"temBAD_TRANSFER_RATE" : -280,
"temBAD_WEIGHT" : -270,
"temCANNOT_PREAUTH_SELF" : -267,
"temDISABLED" : -273,
"temDST_IS_SRC" : -279,
"temDST_NEEDED" : -278,
"temHOOK_DATA_TOO_LARGE" : -253,
"temINVALID" : -277,
"temINVALID_ACCOUNT_ID" : -268,
"temINVALID_COUNT" : -266,
"temINVALID_FLAG" : -276,
"temMALFORMED" : -299,
"temREDUNDANT" : -275,
"temRIPPLE_EMPTY" : -274,
"temSEQ_AND_TICKET" : -263,
"temUNCERTAIN" : -265,
"temUNKNOWN" : -264,
"temXCHAIN_BAD_PROOF" : -259,
"temXCHAIN_BRIDGE_BAD_ISSUES" : -258,
"temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT" : -256,
"temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT" : -255,
"temXCHAIN_BRIDGE_NONDOOR_OWNER" : -257,
"temXCHAIN_EQUAL_DOOR_ACCOUNTS" : -260,
"temXCHAIN_TOO_MANY_ATTESTATIONS" : -254,
"terFUNDS_SPENT" : -98,
"terINSUF_FEE_B" : -97,
"terLAST" : -91,
"terNO_ACCOUNT" : -96,
"terNO_AMM" : -87,
"terNO_AUTH" : -95,
"terNO_HOOK" : -86,
"terNO_LINE" : -94,
"terNO_RIPPLE" : -90,
"terOWNERS" : -93,
"terPRE_SEQ" : -92,
"terPRE_TICKET" : -88,
"terQUEUED" : -89,
"terRETRY" : -99,
"tesSUCCESS" : 0
})json";
{
Env env(*this);
auto const result = env.rpc("server_definitions");
BEAST_EXPECT(!result[jss::result].isMember(jss::error));
// FIELDS
// DA: Not Tested
// LEDGER ENTRY TYPES
BEAST_EXPECT(result[jss::result][jss::status] == "success");
BEAST_EXPECT(result[jss::result].isMember(jss::FIELDS));
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
BEAST_EXPECT(
result[jss::result]["LEDGER_ENTRY_TYPES"] == loadJson(jsonLE));
// TRANSACTION TYPES
BEAST_EXPECT(
result[jss::result]["TRANSACTION_TYPES"] == loadJson(jsonTT));
// TYPES
BEAST_EXPECT(result[jss::result]["TYPES"] == loadJson(jsonTY));
// TRANSACTION_RESULTS
BEAST_EXPECT(
result[jss::result]["TRANSACTION_RESULTS"] ==
loadJson(jsonTEC));
result[jss::result].isMember(jss::TRANSACTION_RESULTS));
BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_TYPES));
BEAST_EXPECT(result[jss::result].isMember(jss::TYPES));
BEAST_EXPECT(result[jss::result].isMember(jss::hash));
BEAST_EXPECT(result[jss::result][jss::status] == "success");
}
}