Merge branch 'dev' into fixXahauV1

This commit is contained in:
Denis Angell
2023-12-11 13:51:11 +01:00
committed by GitHub
16 changed files with 5835 additions and 811 deletions

View File

@@ -755,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/Wildcard_test.cpp
src/test/app/XahauGenesis_test.cpp
src/test/app/tx/apply_test.cpp
@@ -896,6 +897,7 @@ if (tests)
src/test/jtx/impl/token.cpp
src/test/jtx/impl/trust.cpp
src/test/jtx/impl/txflags.cpp
src/test/jtx/impl/unl.cpp
src/test/jtx/impl/uritoken.cpp
src/test/jtx/impl/utility.cpp

View File

@@ -5,7 +5,7 @@ echo "START BUILDING (HOST)"
echo "Cleaning previously built binary"
rm -f release-build/xahaud
BUILD_CORES=$(echo "scale=0 ; `nproc` / 3" | bc)
BUILD_CORES=$(echo "scale=0 ; `nproc` / 1.337" | bc)
if [[ "$GITHUB_REPOSITORY" == "" ]]; then
#Default

View File

@@ -2030,15 +2030,15 @@ TxQ::doRPC(Application& app, std::optional<XRPAmount> hookFeeUnits) const
levels[jss::median_level] = to_string(metrics.medFeeLevel);
levels[jss::open_ledger_level] = to_string(metrics.openLedgerFeeLevel);
auto const baseFee =
view->fees().base + (hookFeeUnits ? hookFeeUnits->drops() : 0);
auto const txFee = XRPAmount{hookFeeUnits->drops()};
auto const baseFee = view->fees().base;
// If the base fee is 0 drops, but escalation has kicked in, treat the
// base fee as if it is 1 drop, which makes the rest of the math
// work.
auto const effectiveBaseFee = [&baseFee, &metrics]() {
if (!baseFee && metrics.openLedgerFeeLevel != metrics.referenceFeeLevel)
auto const effectiveBaseFee = [&txFee, &metrics]() {
if (!txFee && metrics.openLedgerFeeLevel != metrics.referenceFeeLevel)
return XRPAmount{1};
return baseFee;
return txFee;
}();
auto& drops = ret[jss::drops] = Json::Value();

View File

@@ -86,22 +86,6 @@ Invoke::calculateBaseFee(ReadView const& view, STTx const& tx)
extraFee +=
XRPAmount{static_cast<XRPAmount>(tx.getFieldVL(sfBlob).size())};
if (tx.isFieldPresent(sfHookParameters))
{
uint64_t paramBytes = 0;
auto const& params = tx.getFieldArray(sfHookParameters);
for (auto const& param : params)
{
paramBytes += (param.isFieldPresent(sfHookParameterName)
? param.getFieldVL(sfHookParameterName).size()
: 0) +
(param.isFieldPresent(sfHookParameterValue)
? param.getFieldVL(sfHookParameterValue).size()
: 0);
}
extraFee += XRPAmount{static_cast<XRPAmount>(paramBytes)};
}
return Transactor::calculateBaseFee(view, tx) + extraFee;
}

View File

@@ -350,6 +350,23 @@ Transactor::calculateBaseFee(ReadView const& view, STTx const& tx)
XRPAmount accumulator = baseFee;
if (view.rules().enabled(featureHooks) &&
tx.isFieldPresent(sfHookParameters))
{
uint64_t paramBytes = 0;
auto const& params = tx.getFieldArray(sfHookParameters);
for (auto const& param : params)
{
paramBytes += (param.isFieldPresent(sfHookParameterName)
? param.getFieldVL(sfHookParameterName).size()
: 0) +
(param.isFieldPresent(sfHookParameterValue)
? param.getFieldVL(sfHookParameterValue).size()
: 0);
}
accumulator += XRPAmount{static_cast<XRPAmount>(paramBytes)};
}
// fee based on memos, 1 drop per byte
if (tx.isFieldPresent(sfMemos))
{

View File

@@ -371,7 +371,6 @@ invoke_calculateBaseFee(ReadView const& view, STTx const& tx)
case ttURITOKEN_CANCEL_SELL_OFFER:
return URIToken::calculateBaseFee(view, tx);
default:
assert(false);
return XRPAmount{0};
}
}

View File

@@ -422,11 +422,13 @@ doServerDefinitions(RPC::JsonContext& context)
uint32_t curLgrSeq = context.ledgerMaster.getValidatedLedger()->info().seq;
// static values used for cache
static uint32_t lastGenerated = 0; // last ledger seq it was generated
static Json::Value lastFeatures{
Json::objectValue}; // the actual features JSON last generated
static uint256 lastFeatureHash; // the hash of the features JSON last time
// it was generated
static thread_local uint32_t lastGenerated =
0; // last ledger seq it was generated
static thread_local Json::Value lastFeatures{
Json::objectValue}; // the actual features JSON last generated
static thread_local uint256
lastFeatureHash; // the hash of the features JSON last time
// it was generated
// if a flag ledger has passed since it was last generated, regenerate it,
// update the cache above

View File

@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 Ripple Labs Inc.
Copyright (c) 2023 XRPL-Labs
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -20,6 +20,7 @@
#include <ripple/protocol/Feature.h>
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/jss.h>
#include <test/app/Import_json.h>
#include <test/jtx.h>
namespace ripple {
@@ -27,6 +28,294 @@ namespace test {
class BaseFee_test : public beast::unit_test::suite
{
Json::Value
addTxParams(Json::Value jv)
{
jv[jss::HookParameters] = Json::Value{Json::arrayValue};
jv[jss::HookParameters][0U] = Json::Value{};
jv[jss::HookParameters][0U][jss::HookParameter] = Json::Value{};
jv[jss::HookParameters][0U][jss::HookParameter]
[jss::HookParameterName] = "CAFE";
jv[jss::HookParameters][0U][jss::HookParameter]
[jss::HookParameterValue] = "DEADBEEF";
return jv;
}
void
testRPCCall(jtx::Env& env, Json::Value tx, std::string expected)
{
auto const jv = addTxParams(tx);
auto const jtx = env.jt(jv);
auto const feeDrops = env.current()->fees().base;
// 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 base fee & open ledger fee
auto const drops = jrr[jss::result][jss::drops];
auto const baseFee = drops[jss::base_fee];
BEAST_EXPECT(baseFee == to_string(feeDrops));
auto const openLedgerFee = drops[jss::open_ledger_fee];
BEAST_EXPECT(openLedgerFee == expected);
// verify hooks fee
auto const hooksFee = jrr[jss::result][jss::fee_hooks_feeunits];
BEAST_EXPECT(hooksFee == expected);
}
void
testAccountSet(FeatureBitset features)
{
testcase("account set w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
auto tx = fset(account, asfTshCollect);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testAccountDelete(FeatureBitset features)
{
testcase("account delete w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const bene = Account("bob");
env.fund(XRP(1000), account, bene);
env.close();
// build tx
auto tx = acctdelete(account, bene);
// verify hooks fee
testRPCCall(env, tx, "200000");
}
static uint256
getCheckIndex(AccountID const& account, std::uint32_t uSequence)
{
return keylet::check(account, uSequence).key;
}
void
testCheckCancel(FeatureBitset features)
{
testcase("check cancel w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
uint256 const checkId{getCheckIndex(account, env.seq(account))};
auto tx = check::cancel(account, checkId);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testCheckCash(FeatureBitset features)
{
testcase("check cash w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const dest = Account("bob");
env.fund(XRP(1000), account, dest);
env.close();
// build tx
uint256 const checkId{getCheckIndex(account, env.seq(account))};
auto tx = check::cash(dest, checkId, XRP(100));
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testCheckCreate(FeatureBitset features)
{
testcase("check create w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const dest = Account("bob");
env.fund(XRP(1000), account, dest);
env.close();
// build tx
auto tx = check::create(account, dest, XRP(100));
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testClaimReward(FeatureBitset features)
{
testcase("claim reward w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
auto tx = reward::claim(account);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testDepositPreauth(FeatureBitset features)
{
testcase("deposit preauth w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const authed = Account("bob");
env.fund(XRP(1000), account, authed);
env.close();
// build tx
auto tx = deposit::auth(account, authed);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testEscrowCancel(FeatureBitset features)
{
testcase("escrow cancel w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
auto const seq1 = env.seq(account);
auto tx = escrow::cancel(account, account, seq1);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testEscrowCreate(FeatureBitset features)
{
testcase("escrow create w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const dest = Account("bob");
env.fund(XRP(1000), account, dest);
env.close();
// build tx
auto tx = escrow::create(account, dest, XRP(10));
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testEscrowFinish(FeatureBitset features)
{
testcase("escrow finish w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
auto const seq1 = env.seq(account);
auto tx = escrow::finish(account, account, seq1);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testImport(FeatureBitset features)
{
testcase("import w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
auto tx = import::import(
account, import::loadXpop(ImportTCAccountSet::w_seed));
// verify hooks fee
testRPCCall(env, tx, "106");
}
void
testInvoke(FeatureBitset features)
{
@@ -35,78 +324,443 @@ class BaseFee_test : public beast::unit_test::suite
using namespace test::jtx;
using namespace std::literals;
test::jtx::Env env{*this, network::makeNetworkConfig(21337)};
Env env{*this, network::makeNetworkConfig(21337)};
auto const alice = Account("alice");
env.fund(XRP(1000), alice);
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
auto tx = invoke::invoke(alice);
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));
auto tx = invoke::invoke(account);
// verify hooks fee
auto const hooksFee = jrr[jss::result][jss::fee_hooks_feeunits];
BEAST_EXPECT(hooksFee == "16");
testRPCCall(env, tx, "16");
}
void
testURITokenFee(FeatureBitset features)
testOfferCancel(FeatureBitset features)
{
testcase("uritoken w/ hook params");
testcase("offer cancel w/ hook params");
using namespace test::jtx;
using namespace std::literals;
test::jtx::Env env{*this, network::makeNetworkConfig(21337)};
Env env{*this, network::makeNetworkConfig(21337)};
auto const alice = Account("alice");
env.fund(XRP(1000), alice);
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
auto const offerSeq = env.seq(account);
auto tx = offer_cancel(account, offerSeq);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testOfferCreate(FeatureBitset features)
{
testcase("offer create w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const gw = Account("gw");
auto const USD = gw["USD"];
env.fund(XRP(1000), account);
env.close();
// build tx
auto tx = offer(account, USD(1000), XRP(1000));
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testPayment(FeatureBitset features)
{
testcase("payment w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const dest = Account("bob");
env.fund(XRP(1000), account, dest);
env.close();
// build tx
auto tx = pay(account, dest, XRP(1));
// verify hooks fee
testRPCCall(env, tx, "16");
}
static uint256
channel(
jtx::Account const& account,
jtx::Account const& dst,
std::uint32_t seqProxyValue)
{
auto const k = keylet::payChan(account, dst, seqProxyValue);
return k.key;
}
void
testPaymentChannelClaim(FeatureBitset features)
{
testcase("payment channel claim w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const dest = Account("bob");
env.fund(XRP(1000), account, dest);
env.close();
// build tx
auto const chan = channel(account, dest, env.seq(account));
auto const delta = XRP(1);
auto const reqBal = delta;
auto const authAmt = reqBal + XRP(1);
auto tx = paychan::claim(account, chan, reqBal, authAmt);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testPaymentChannelCreate(FeatureBitset features)
{
testcase("payment channel create w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const dest = Account("bob");
env.fund(XRP(1000), account, dest);
env.close();
// build tx
auto const pk = account.pk();
auto const settleDelay = 100s;
auto tx = paychan::create(account, dest, XRP(10), settleDelay, pk);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testPaymentChannelFund(FeatureBitset features)
{
testcase("payment channel fund w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const dest = Account("bob");
env.fund(XRP(1000), account, dest);
env.close();
// build tx
auto const chan = channel(account, dest, env.seq(account));
auto tx = paychan::fund(account, chan, XRP(1));
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testSetHook(FeatureBitset features)
{
testcase("set hook w/ hook params and otxn params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
auto tx = genesis::setAcceptHook(account);
// add hook params
tx[jss::Hooks][0u][jss::Hook][jss::HookParameters] =
Json::Value{Json::arrayValue};
tx[jss::Hooks][0u][jss::Hook][jss::HookParameters][0U] = Json::Value{};
Json::Value& hookParams =
tx[jss::Hooks][0u][jss::Hook][jss::HookParameters][0U];
hookParams[jss::HookParameter] = Json::Value{};
hookParams[jss::HookParameter][jss::HookParameterName] = "CAFE";
hookParams[jss::HookParameter][jss::HookParameterValue] = "DEADBEEF";
// verify hooks fee
testRPCCall(env, tx, "73022");
}
void
testSetRegularKey(FeatureBitset features)
{
testcase("set regular key w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const dest = Account("bob");
env.fund(XRP(1000), account, dest);
env.close();
// build tx
auto tx = regkey(account, dest);
// verify hooks fee
testRPCCall(env, tx, "0");
}
void
testSignersListSet(FeatureBitset features)
{
testcase("signers list set w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const signer1 = Account("bob");
auto const signer2 = Account("carol");
env.fund(XRP(1000), account, signer1, signer2);
env.close();
// build tx
auto tx = signers(account, 2, {{signer1, 1}, {signer2, 1}});
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testTicketCreate(FeatureBitset features)
{
testcase("ticket create w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
auto tx = ticket::create(account, 2);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testTrustSet(FeatureBitset features)
{
testcase("trust set w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
auto const gw = Account("gw");
auto const USD = gw["USD"];
env.fund(XRP(1000), account, gw);
env.close();
// build tx
auto tx = trust(account, USD(1000));
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testURITokenBurnFee(FeatureBitset features)
{
testcase("uritoken burn w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const issuer = Account("alice");
env.fund(XRP(1000), issuer);
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));
auto const tid = uritoken::tokenid(issuer, uri);
std::string const hexid{strHex(tid)};
auto tx = uritoken::burn(issuer, hexid);
// verify hooks fee
auto const hooksFee = jrr[jss::result][jss::fee_hooks_feeunits];
BEAST_EXPECT(hooksFee == "10");
testRPCCall(env, tx, "16");
}
void
testURITokenBuyFee(FeatureBitset features)
{
testcase("uritoken buy w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const issuer = Account("alice");
env.fund(XRP(1000), issuer);
env.close();
// build tx
std::string const uri(maxTokenURILength, '?');
auto const tid = uritoken::tokenid(issuer, uri);
std::string const hexid{strHex(tid)};
auto tx = uritoken::buy(issuer, hexid);
tx[jss::Amount] = "1000000";
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testURITokenCancelSellOfferFee(FeatureBitset features)
{
testcase("uritoken cancel sell offer w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const issuer = Account("alice");
env.fund(XRP(1000), issuer);
env.close();
// build tx
std::string const uri(maxTokenURILength, '?');
auto const tid = uritoken::tokenid(issuer, uri);
std::string const hexid{strHex(tid)};
auto tx = uritoken::cancel(issuer, hexid);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testURITokenCreateSellOfferFee(FeatureBitset features)
{
testcase("uritoken create sell offer w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const issuer = Account("alice");
auto const buyer = Account("bob");
env.fund(XRP(1000), issuer, buyer);
env.close();
// build tx
std::string const uri(maxTokenURILength, '?');
auto const tid = uritoken::tokenid(issuer, uri);
std::string const hexid{strHex(tid)};
auto tx = uritoken::sell(issuer, hexid);
tx[jss::Destination] = buyer.human();
tx[jss::Amount] = "1000000";
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testURITokenMintFee(FeatureBitset features)
{
testcase("uritoken mint w/ hook params");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, network::makeNetworkConfig(21337)};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// build tx
std::string const uri(maxTokenURILength, '?');
auto tx = uritoken::mint(account, uri);
// verify hooks fee
testRPCCall(env, tx, "16");
}
void
testWithFeats(FeatureBitset features)
{
testAccountSet(features);
testAccountDelete(features);
testCheckCancel(features);
testCheckCash(features);
testCheckCreate(features);
testClaimReward(features);
testDepositPreauth(features);
testEscrowCancel(features);
testEscrowCreate(features);
testEscrowFinish(features);
// testGenesisMint(features); // N/A
testImport(features);
testInvoke(features);
testURITokenFee(features);
testOfferCancel(features);
testOfferCreate(features);
testPayment(features);
testPaymentChannelClaim(features);
testPaymentChannelCreate(features);
testPaymentChannelFund(features);
testSetHook(features);
testSetRegularKey(features);
testSignersListSet(features);
testTicketCreate(features);
testTrustSet(features);
testURITokenBurnFee(features);
testURITokenBuyFee(features);
testURITokenCancelSellOfferFee(features);
testURITokenCreateSellOfferFee(features);
testURITokenMintFee(features);
}
public:

View File

@@ -5549,73 +5549,6 @@ class Import_test : public beast::unit_test::suite
}
}
// std::unique_ptr<Config>
// network::makeGenesisConfig(
// FeatureBitset features,
// uint32_t networkID,
// std::string fee,
// std::string a_res,
// std::string o_res,
// uint32_t ledgerID)
// {
// using namespace jtx;
// // IMPORT VL KEY
// std::vector<std::string> const keys = {
// "ED74D4036C6591A4BDF9C54CEFA39B996A"
// "5DCE5F86D11FDA1874481CE9D5A1CDC1"};
// Json::Value jsonValue;
// Json::Reader reader;
// reader.parse(ImportTCHalving::base_genesis, jsonValue);
// foreachFeature(features, [&](uint256 const& feature) {
// std::string featureName = featureToName(feature);
// std::optional<uint256> featureHash =
// getRegisteredFeature(featureName);
// if (featureHash.has_value())
// {
// std::string hashString = to_string(featureHash.value());
// jsonValue["ledger"]["accountState"][1]["Amendments"].append(
// hashString);
// }
// });
// jsonValue["ledger_current_index"] = ledgerID;
// jsonValue["ledger"]["ledger_index"] = to_string(ledgerID);
// jsonValue["ledger"]["seqNum"] = to_string(ledgerID);
// return envconfig([&](std::unique_ptr<Config> cfg) {
// cfg->NETWORK_ID = networkID;
// cfg->START_LEDGER = jsonValue.toStyledString();
// cfg->START_UP = Config::LOAD_JSON;
// 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;
// });
// }
void
testHalving(FeatureBitset features)
{
@@ -5965,40 +5898,6 @@ class Import_test : public beast::unit_test::suite
}
}
void
testRPCFee(FeatureBitset features)
{
testcase("rpc fee");
using namespace test::jtx;
using namespace std::literals;
test::jtx::Env env{*this, network::makeNetworkConfig(21337)};
auto const feeDrops = env.current()->fees().base;
auto const alice = Account("alice");
env.fund(XRP(1000), alice);
env.close();
// build tx_blob
Json::Value params;
auto const xpopJson = import::loadXpop(ImportTCAccountSet::w_seed);
auto tx = env.jt(import::import(alice, xpopJson));
params[jss::tx_blob] = strHex(tx.stx->getSerializer().slice());
// fee request
auto const jrr = env.rpc("json", "fee", to_string(params));
// verify hooks fee
auto const hooksFee = jrr[jss::result][jss::fee_hooks_feeunits];
BEAST_EXPECT(hooksFee == to_string(feeDrops * 10));
// verify open ledger fee
auto const dropsJV = jrr[jss::result][jss::drops];
auto const openLedgerFee = dropsJV[jss::open_ledger_fee];
BEAST_EXPECT(openLedgerFee == to_string((feeDrops * 10) + feeDrops));
}
public:
void
run() override
@@ -6037,7 +5936,6 @@ public:
testMaxSupply(features);
testMinMax(features);
testHalving(features - featureOwnerPaysFee);
testRPCFee(features);
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -42,35 +42,6 @@ namespace test {
* are put in their existing unit test files.
*/
/**
* Test the size of the negative UNL in a ledger,
* also test if the ledger has ToDisalbe and/or ToReEnable
*
* @param l the ledger
* @param size the expected negative UNL size
* @param hasToDisable if expect ToDisable in ledger
* @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);
/**
* 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
*/
bool
applyAndTestResult(jtx::Env& env, OpenView& view, STTx const& tx, bool pass);
/**
* Verify the content of negative UNL entries (public key and ledger sequence)
* of a ledger
@@ -85,15 +56,6 @@ VerifyPubKeyAndSeq(
std::shared_ptr<Ledger const> const& l,
hash_map<PublicKey, std::uint32_t> nUnlLedgerSeq);
/**
* Count the number of Tx in a TxSet
*
* @param txSet the TxSet
* @return the number of Tx
*/
std::size_t
countTx(std::shared_ptr<SHAMap> const& txSet);
/**
* Create fake public keys
*
@@ -103,17 +65,6 @@ countTx(std::shared_ptr<SHAMap> const& txSet);
std::vector<PublicKey>
createPublicKeys(std::size_t n);
/**
* 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
*/
STTx
createTx(bool disabling, LedgerIndex seq, PublicKey const& txKey);
class NegativeUNL_test : public beast::unit_test::suite
{
/**
@@ -245,14 +196,16 @@ class NegativeUNL_test : public beast::unit_test::suite
l = std::make_shared<Ledger>(
*l, env.app().timeKeeper().closeTime());
auto txDisable_0 = createTx(true, l->seq(), publicKeys[0]);
auto txReEnable_1 = createTx(false, l->seq(), publicKeys[1]);
auto txDisable_0 = unl::createTx(true, l->seq(), publicKeys[0]);
auto txReEnable_1 = unl::createTx(false, l->seq(), publicKeys[1]);
OpenView accum(&*l);
BEAST_EXPECT(applyAndTestResult(env, accum, txDisable_0, false));
BEAST_EXPECT(applyAndTestResult(env, accum, txReEnable_1, false));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txDisable_0, false));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txReEnable_1, false));
accum.apply(*l);
BEAST_EXPECT(negUnlSizeTest(l, 0, false, false));
BEAST_EXPECT(unl::negUnlSizeTest(l, 0, false, false));
}
{
@@ -266,18 +219,21 @@ class NegativeUNL_test : public beast::unit_test::suite
BEAST_EXPECT(l->isFlagLedger());
l->updateNegativeUNL();
auto txDisable_0 = createTx(true, l->seq(), publicKeys[0]);
auto txDisable_1 = createTx(true, l->seq(), publicKeys[1]);
auto txReEnable_2 = createTx(false, l->seq(), publicKeys[2]);
auto txDisable_0 = unl::createTx(true, l->seq(), publicKeys[0]);
auto txDisable_1 = unl::createTx(true, l->seq(), publicKeys[1]);
auto txReEnable_2 = unl::createTx(false, l->seq(), publicKeys[2]);
// can apply 1 and only 1 ToDisable Tx,
// cannot apply ToReEnable Tx, since negative UNL is empty
OpenView accum(&*l);
BEAST_EXPECT(applyAndTestResult(env, accum, txDisable_0, true));
BEAST_EXPECT(applyAndTestResult(env, accum, txDisable_1, false));
BEAST_EXPECT(applyAndTestResult(env, accum, txReEnable_2, false));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txDisable_0, true));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txDisable_1, false));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txReEnable_2, false));
accum.apply(*l);
auto good_size = negUnlSizeTest(l, 0, true, false);
auto good_size = unl::negUnlSizeTest(l, 0, true, false);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -292,7 +248,7 @@ class NegativeUNL_test : public beast::unit_test::suite
//(3) ledgers before the next flag ledger
for (auto i = 0; i < 256; ++i)
{
auto good_size = negUnlSizeTest(l, 0, true, false);
auto good_size = unl::negUnlSizeTest(l, 0, true, false);
BEAST_EXPECT(good_size);
if (good_size)
BEAST_EXPECT(l->validatorToDisable() == publicKeys[0]);
@@ -304,7 +260,7 @@ class NegativeUNL_test : public beast::unit_test::suite
//(4) next flag ledger
// test if the ledger updated correctly
auto good_size = negUnlSizeTest(l, 1, false, false);
auto good_size = unl::negUnlSizeTest(l, 1, false, false);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -312,20 +268,25 @@ class NegativeUNL_test : public beast::unit_test::suite
nUnlLedgerSeq.emplace(publicKeys[0], l->seq());
}
auto txDisable_0 = createTx(true, l->seq(), publicKeys[0]);
auto txDisable_1 = createTx(true, l->seq(), publicKeys[1]);
auto txReEnable_0 = createTx(false, l->seq(), publicKeys[0]);
auto txReEnable_1 = createTx(false, l->seq(), publicKeys[1]);
auto txReEnable_2 = createTx(false, l->seq(), publicKeys[2]);
auto txDisable_0 = unl::createTx(true, l->seq(), publicKeys[0]);
auto txDisable_1 = unl::createTx(true, l->seq(), publicKeys[1]);
auto txReEnable_0 = unl::createTx(false, l->seq(), publicKeys[0]);
auto txReEnable_1 = unl::createTx(false, l->seq(), publicKeys[1]);
auto txReEnable_2 = unl::createTx(false, l->seq(), publicKeys[2]);
OpenView accum(&*l);
BEAST_EXPECT(applyAndTestResult(env, accum, txDisable_0, false));
BEAST_EXPECT(applyAndTestResult(env, accum, txDisable_1, true));
BEAST_EXPECT(applyAndTestResult(env, accum, txReEnable_1, false));
BEAST_EXPECT(applyAndTestResult(env, accum, txReEnable_2, false));
BEAST_EXPECT(applyAndTestResult(env, accum, txReEnable_0, true));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txDisable_0, false));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txDisable_1, true));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txReEnable_1, false));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txReEnable_2, false));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txReEnable_0, true));
accum.apply(*l);
good_size = negUnlSizeTest(l, 1, true, true);
good_size = unl::negUnlSizeTest(l, 1, true, true);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -341,7 +302,7 @@ class NegativeUNL_test : public beast::unit_test::suite
//(5) ledgers before the next flag ledger
for (auto i = 0; i < 256; ++i)
{
auto good_size = negUnlSizeTest(l, 1, true, true);
auto good_size = unl::negUnlSizeTest(l, 1, true, true);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -357,19 +318,20 @@ class NegativeUNL_test : public beast::unit_test::suite
//(6) next flag ledger
// test if the ledger updated correctly
auto good_size = negUnlSizeTest(l, 1, false, false);
auto good_size = unl::negUnlSizeTest(l, 1, false, false);
BEAST_EXPECT(good_size);
if (good_size)
{
BEAST_EXPECT(l->negativeUNL().count(publicKeys[1]));
}
auto txDisable_0 = createTx(true, l->seq(), publicKeys[0]);
auto txDisable_0 = unl::createTx(true, l->seq(), publicKeys[0]);
OpenView accum(&*l);
BEAST_EXPECT(applyAndTestResult(env, accum, txDisable_0, true));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txDisable_0, true));
accum.apply(*l);
good_size = negUnlSizeTest(l, 1, true, false);
good_size = unl::negUnlSizeTest(l, 1, true, false);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -385,7 +347,7 @@ class NegativeUNL_test : public beast::unit_test::suite
//(7) ledgers before the next flag ledger
for (auto i = 0; i < 256; ++i)
{
auto good_size = negUnlSizeTest(l, 1, true, false);
auto good_size = unl::negUnlSizeTest(l, 1, true, false);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -400,7 +362,7 @@ class NegativeUNL_test : public beast::unit_test::suite
//(8) next flag ledger
// test if the ledger updated correctly
auto good_size = negUnlSizeTest(l, 2, false, false);
auto good_size = unl::negUnlSizeTest(l, 2, false, false);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -410,16 +372,19 @@ class NegativeUNL_test : public beast::unit_test::suite
BEAST_EXPECT(VerifyPubKeyAndSeq(l, nUnlLedgerSeq));
}
auto txDisable_0 = createTx(true, l->seq(), publicKeys[0]);
auto txReEnable_0 = createTx(false, l->seq(), publicKeys[0]);
auto txReEnable_1 = createTx(false, l->seq(), publicKeys[1]);
auto txDisable_0 = unl::createTx(true, l->seq(), publicKeys[0]);
auto txReEnable_0 = unl::createTx(false, l->seq(), publicKeys[0]);
auto txReEnable_1 = unl::createTx(false, l->seq(), publicKeys[1]);
OpenView accum(&*l);
BEAST_EXPECT(applyAndTestResult(env, accum, txReEnable_0, true));
BEAST_EXPECT(applyAndTestResult(env, accum, txReEnable_1, false));
BEAST_EXPECT(applyAndTestResult(env, accum, txDisable_0, false));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txReEnable_0, true));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txReEnable_1, false));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txDisable_0, false));
accum.apply(*l);
good_size = negUnlSizeTest(l, 2, false, true);
good_size = unl::negUnlSizeTest(l, 2, false, true);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -434,7 +399,7 @@ class NegativeUNL_test : public beast::unit_test::suite
//(9) ledgers before the next flag ledger
for (auto i = 0; i < 256; ++i)
{
auto good_size = negUnlSizeTest(l, 2, false, true);
auto good_size = unl::negUnlSizeTest(l, 2, false, true);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -450,7 +415,7 @@ class NegativeUNL_test : public beast::unit_test::suite
//(10) next flag ledger
// test if the ledger updated correctly
auto good_size = negUnlSizeTest(l, 1, false, false);
auto good_size = unl::negUnlSizeTest(l, 1, false, false);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -459,12 +424,13 @@ class NegativeUNL_test : public beast::unit_test::suite
BEAST_EXPECT(VerifyPubKeyAndSeq(l, nUnlLedgerSeq));
}
auto txReEnable_1 = createTx(false, l->seq(), publicKeys[1]);
auto txReEnable_1 = unl::createTx(false, l->seq(), publicKeys[1]);
OpenView accum(&*l);
BEAST_EXPECT(applyAndTestResult(env, accum, txReEnable_1, true));
BEAST_EXPECT(
unl::applyAndTestResult(env, accum, txReEnable_1, true));
accum.apply(*l);
good_size = negUnlSizeTest(l, 1, false, true);
good_size = unl::negUnlSizeTest(l, 1, false, true);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -478,7 +444,7 @@ class NegativeUNL_test : public beast::unit_test::suite
//(11) ledgers before the next flag ledger
for (auto i = 0; i < 256; ++i)
{
auto good_size = negUnlSizeTest(l, 1, false, true);
auto good_size = unl::negUnlSizeTest(l, 1, false, true);
BEAST_EXPECT(good_size);
if (good_size)
{
@@ -492,14 +458,14 @@ class NegativeUNL_test : public beast::unit_test::suite
l->updateNegativeUNL();
//(12) next flag ledger
BEAST_EXPECT(negUnlSizeTest(l, 0, false, false));
BEAST_EXPECT(unl::negUnlSizeTest(l, 0, false, false));
}
{
//(13) ledgers before the next flag ledger
for (auto i = 0; i < 256; ++i)
{
BEAST_EXPECT(negUnlSizeTest(l, 0, false, false));
BEAST_EXPECT(unl::negUnlSizeTest(l, 0, false, false));
l = std::make_shared<Ledger>(
*l, env.app().timeKeeper().closeTime());
}
@@ -507,7 +473,7 @@ class NegativeUNL_test : public beast::unit_test::suite
l->updateNegativeUNL();
//(14) next flag ledger
BEAST_EXPECT(negUnlSizeTest(l, 0, false, false));
BEAST_EXPECT(unl::negUnlSizeTest(l, 0, false, false));
}
}
@@ -542,11 +508,11 @@ class NegativeUNLNoAmendment_test : public beast::unit_test::suite
*l, env.app().timeKeeper().closeTime());
}
BEAST_EXPECT(l->seq() == 256);
auto txDisable_0 = createTx(true, l->seq(), publicKeys[0]);
auto txDisable_0 = unl::createTx(true, l->seq(), publicKeys[0]);
OpenView accum(&*l);
BEAST_EXPECT(applyAndTestResult(env, accum, txDisable_0, false));
BEAST_EXPECT(unl::applyAndTestResult(env, accum, txDisable_0, false));
accum.apply(*l);
BEAST_EXPECT(negUnlSizeTest(l, 0, false, false));
BEAST_EXPECT(unl::negUnlSizeTest(l, 0, false, false));
}
void
@@ -634,8 +600,8 @@ struct NetworkHistory
OpenView accum(&*l);
if (l->negativeUNL().size() < param.negUNLSize)
{
auto tx = createTx(true, l->seq(), UNLKeys[nidx]);
if (!applyAndTestResult(env, accum, tx, true))
auto tx = unl::createTx(true, l->seq(), UNLKeys[nidx]);
if (!unl::applyAndTestResult(env, accum, tx, true))
break;
++nidx;
}
@@ -643,15 +609,15 @@ struct NetworkHistory
{
if (param.hasToDisable)
{
auto tx = createTx(true, l->seq(), UNLKeys[nidx]);
if (!applyAndTestResult(env, accum, tx, true))
auto tx = unl::createTx(true, l->seq(), UNLKeys[nidx]);
if (!unl::applyAndTestResult(env, accum, tx, true))
break;
++nidx;
}
if (param.hasToReEnable)
{
auto tx = createTx(false, l->seq(), UNLKeys[0]);
if (!applyAndTestResult(env, accum, tx, true))
auto tx = unl::createTx(false, l->seq(), UNLKeys[0]);
if (!unl::applyAndTestResult(env, accum, tx, true))
break;
}
}
@@ -659,7 +625,7 @@ struct NetworkHistory
}
l->updateSkipList();
}
return negUnlSizeTest(
return unl::negUnlSizeTest(
l, param.negUNLSize, param.hasToDisable, param.hasToReEnable);
}
@@ -759,7 +725,7 @@ voteAndCheck(
vote.doVoting(
history.lastLedger(), history.UNLKeySet, history.validations, txSet);
return countTx(txSet) >= expect;
return unl::countTx(txSet) >= expect;
}
/**
@@ -782,11 +748,11 @@ class NegativeUNLVoteInternal_test : public beast::unit_test::suite
PublicKey toDisableKey;
PublicKey toReEnableKey;
LedgerIndex seq(1234);
BEAST_EXPECT(countTx(txSet) == 0);
BEAST_EXPECT(unl::countTx(txSet) == 0);
vote.addTx(seq, toDisableKey, NegativeUNLVote::ToDisable, txSet);
BEAST_EXPECT(countTx(txSet) == 1);
BEAST_EXPECT(unl::countTx(txSet) == 1);
vote.addTx(seq, toReEnableKey, NegativeUNLVote::ToReEnable, txSet);
BEAST_EXPECT(countTx(txSet) == 2);
BEAST_EXPECT(unl::countTx(txSet) == 2);
// content of a tx is implicitly tested after applied to a ledger
// in later test cases
}
@@ -1912,31 +1878,6 @@ BEAST_DEFINE_TESTSUITE(NegativeUNLVoteFilterValidations, consensus, ripple);
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
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
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;
}
bool
VerifyPubKeyAndSeq(
@@ -1975,34 +1916,6 @@ VerifyPubKeyAndSeq(
return nUnlLedgerSeq.size() == 0;
}
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;
};
std::vector<PublicKey>
createPublicKeys(std::size_t n)
{
@@ -2019,16 +1932,5 @@ createPublicKeys(std::size_t n)
return keys;
}
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);
}
} // namespace test
} // namespace ripple

View File

@@ -51,23 +51,6 @@ namespace test {
// * are put in their existing unit test files.
// */
// /**
// * Test the size of the negative UNL in a ledger,
// * also test if the ledger has ToDisalbe and/or ToReEnable
// *
// * @param l the ledger
// * @param size the expected negative UNL size
// * @param hasToDisable if expect ToDisable in ledger
// * @param hasToReEnable if expect ToDisable in ledger
// * @return true if meet all three expectation
// */
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
// *
@@ -110,9 +93,6 @@ countUNLRTx(std::shared_ptr<SHAMap> const& txSet);
std::vector<std::string> const keys = {
"ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC1"};
std::unique_ptr<Config>
makeNetworkVLConfig(uint32_t networkID, std::vector<std::string> keys);
/**
* Verify if the UNL report exists
*
@@ -165,38 +145,6 @@ 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
@@ -345,7 +293,10 @@ class UNLReport_test : public beast::unit_test::suite
// telIMPORT_VL_KEY_NOT_RECOGNISED
{
test::jtx::Env env{
*this, makeNetworkVLConfig(21337, keys), features, nullptr};
*this,
jtx::network::makeNetworkVLConfig(21337, keys),
features,
nullptr};
auto l = std::make_shared<Ledger>(
create_genesis,
@@ -374,7 +325,10 @@ class UNLReport_test : public beast::unit_test::suite
// SUCCESS
{
test::jtx::Env env{
*this, makeNetworkVLConfig(21337, keys), features, nullptr};
*this,
jtx::network::makeNetworkVLConfig(21337, keys),
features,
nullptr};
auto l = std::make_shared<Ledger>(
create_genesis,
@@ -413,7 +367,10 @@ class UNLReport_test : public beast::unit_test::suite
using namespace jtx;
test::jtx::Env env{
*this, makeNetworkVLConfig(21337, keys), features, nullptr};
*this,
jtx::network::makeNetworkVLConfig(21337, keys),
features,
nullptr};
std::vector<PublicKey> ivlKeys;
for (auto const& strPk : _ivlKeys)
@@ -674,7 +631,8 @@ struct URNetworkHistory
URNetworkHistory(beast::unit_test::suite& suite, Parameter const& p)
: env(suite,
p.withVL ? makeNetworkVLConfig(21337, keys) : jtx::envconfig(),
p.withVL ? jtx::network::makeNetworkVLConfig(21337, keys)
: jtx::envconfig(),
jtx::supported_amendments() | featureNegativeUNL)
, param(p)
, validations(env.app().getValidations())
@@ -728,8 +686,8 @@ struct URNetworkHistory
OpenView accum(&*l);
if (l->negativeUNL().size() < param.negUNLSize)
{
auto tx = createTx(true, l->seq(), UNLKeys[nidx]);
if (!applyAndTestResult(env, accum, tx, true))
auto tx = unl::createTx(true, l->seq(), UNLKeys[nidx]);
if (!unl::applyAndTestResult(env, accum, tx, true))
break;
++nidx;
}
@@ -737,15 +695,15 @@ struct URNetworkHistory
{
if (param.hasToDisable)
{
auto tx = createTx(true, l->seq(), UNLKeys[nidx]);
if (!applyAndTestResult(env, accum, tx, true))
auto tx = unl::createTx(true, l->seq(), UNLKeys[nidx]);
if (!unl::applyAndTestResult(env, accum, tx, true))
break;
++nidx;
}
if (param.hasToReEnable)
{
auto tx = createTx(false, l->seq(), UNLKeys[0]);
if (!applyAndTestResult(env, accum, tx, true))
auto tx = unl::createTx(false, l->seq(), UNLKeys[0]);
if (!unl::applyAndTestResult(env, accum, tx, true))
break;
}
}
@@ -753,7 +711,7 @@ struct URNetworkHistory
}
l->updateSkipList();
}
return negUnlSizeTest(
return unl::negUnlSizeTest(
l, param.negUNLSize, param.hasToDisable, param.hasToReEnable);
}
@@ -854,7 +812,8 @@ voteAndCheckUNLR(
vote.doVoting(
history.lastLedger(), history.UNLKeySet, history.validations, txSet);
return countUNLRTx(txSet) == expectReport && countTx(txSet) >= expectModify;
return countUNLRTx(txSet) == expectReport &&
unl::countTx(txSet) >= expectModify;
}
/*
@@ -1235,22 +1194,6 @@ 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)
{
@@ -1313,38 +1256,6 @@ countUNLRTx(std::shared_ptr<SHAMap> const& txSet)
return count;
};
std::unique_ptr<Config>
makeNetworkVLConfig(uint32_t networkID, 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 = 10",
"account_reserve = 1000000",
"owner_reserve = 200000"});
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;
});
}
bool
hasUNLReport(jtx::Env const& env)
{
@@ -1412,54 +1323,5 @@ 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

@@ -70,6 +70,7 @@
#include <test/jtx/token.h>
#include <test/jtx/trust.h>
#include <test/jtx/txflags.h>
#include <test/jtx/unl.h>
#include <test/jtx/uritoken.h>
#include <test/jtx/utility.h>

95
src/test/jtx/impl/unl.cpp Normal file
View File

@@ -0,0 +1,95 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2023 XRPL Labs
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/app/tx/apply.h>
#include <ripple/protocol/jss.h>
#include <test/jtx/unl.h>
namespace ripple {
namespace test {
namespace unl {
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
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;
}
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;
};
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);
}
} // namespace unl
} // namespace test
} // namespace ripple

86
src/test/jtx/unl.h Normal file
View File

@@ -0,0 +1,86 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2023 XRPL Labs
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_UNL_H_INCLUDED
#define RIPPLE_TEST_JTX_UNL_H_INCLUDED
#include <ripple/protocol/STAmount.h>
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
namespace ripple {
namespace test {
namespace unl {
/**
* Test the size of the negative UNL in a ledger,
* also test if the ledger has ToDisalbe and/or ToReEnable
*
* @param l the ledger
* @param size the expected negative UNL size
* @param hasToDisable if expect ToDisable in ledger
* @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);
/**
* 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
*/
bool
applyAndTestResult(jtx::Env& env, OpenView& view, STTx const& tx, bool pass);
/**
* Count the number of Tx in a TxSet
*
* @param txSet the TxSet
* @return the number of Tx
*/
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
*/
STTx
createTx(bool disabling, LedgerIndex seq, PublicKey const& txKey);
} // namespace unl
} // namespace test
} // namespace ripple
#endif // RIPPLE_TEST_JTX_UNL_H_INCLUDED

View File

@@ -54,310 +54,17 @@ public:
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].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");
}
}