mirror of
https://github.com/Xahau/xahaud.git
synced 2026-06-04 17:26:39 +00:00
Add AMM functionality: - InstanceCreate - Deposit - Withdraw - Governance - Auctioning - payment engine integration To support this functionality, add: - New RPC method, `amm_info`, to fetch pool and LPT balances - AMM Root Account - trust line for each IOU AMM token - trust line to track Liquidity Provider Tokens (LPT) - `ltAMM` object The `ltAMM` object tracks: - fee votes - auction slot bids - AMM tokens pair - total outstanding tokens balance - `AMMID` to AMM `RootAccountID` mapping Add new classes to facilitate AMM integration into the payment engine. `BookStep` uses these classes to infer if AMM liquidity can be consumed. The AMM formula implementation uses the new Number class added in #4192. IOUAmount and STAmount use Number arithmetic. Add AMM unit tests for all features. AMM requires the following amendments: - featureAMM - fixUniversalNumber - featureFlowCross Notes: - Current trading fee threshold is 1% - AMM currency is generated by: 0x03 + 152 bits of sha256{cur1, cur2} - Current max AMM Offers is 30 --------- Co-authored-by: Howard Hinnant <howard.hinnant@gmail.com>
838 lines
24 KiB
C++
838 lines
24 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
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/protocol/Feature.h>
|
|
#include <ripple/protocol/TxFlags.h>
|
|
#include <ripple/protocol/jss.h>
|
|
#include <test/app/Import_json.h>
|
|
#include <test/jtx.h>
|
|
#include <test/jtx/TestHelpers.h>
|
|
|
|
namespace ripple {
|
|
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_no_hooks];
|
|
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), features};
|
|
|
|
auto const account = Account("alice");
|
|
env.fund(XRP(1000), account);
|
|
env.close();
|
|
|
|
// build tx
|
|
auto tx = fset(account, asfTshCollect);
|
|
|
|
// verify hooks fee
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testAccountDelete(FeatureBitset features)
|
|
{
|
|
testcase("account delete w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "200000" : "200000";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
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), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testCheckCash(FeatureBitset features)
|
|
{
|
|
testcase("check cash w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testCheckCreate(FeatureBitset features)
|
|
{
|
|
testcase("check create w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testClaimReward(FeatureBitset features)
|
|
{
|
|
testcase("claim reward w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
auto const account = Account("alice");
|
|
env.fund(XRP(1000), account);
|
|
env.close();
|
|
|
|
// build tx
|
|
auto tx = reward::claim(account);
|
|
|
|
// verify hooks fee
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testDepositPreauth(FeatureBitset features)
|
|
{
|
|
testcase("deposit preauth w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testEscrowCancel(FeatureBitset features)
|
|
{
|
|
testcase("escrow cancel w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
auto const account = Account("alice");
|
|
env.fund(XRP(1000), account);
|
|
env.close();
|
|
|
|
// build tx
|
|
auto const seq1 = env.seq(account);
|
|
auto tx = cancel(account, account, seq1);
|
|
|
|
// verify hooks fee
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testEscrowCreate(FeatureBitset features)
|
|
{
|
|
testcase("escrow create w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
auto const account = Account("alice");
|
|
auto const dest = Account("bob");
|
|
env.fund(XRP(1000), account, dest);
|
|
env.close();
|
|
|
|
// build tx
|
|
auto tx = escrow(account, dest, XRP(10));
|
|
|
|
// verify hooks fee
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testEscrowFinish(FeatureBitset features)
|
|
{
|
|
testcase("escrow finish w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
auto const account = Account("alice");
|
|
env.fund(XRP(1000), account);
|
|
env.close();
|
|
|
|
// build tx
|
|
auto const seq1 = env.seq(account);
|
|
auto tx = finish(account, account, seq1);
|
|
|
|
// verify hooks fee
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testImport(FeatureBitset features)
|
|
{
|
|
testcase("import w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "106" : "100";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testInvoke(FeatureBitset features)
|
|
{
|
|
testcase("invoke w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
auto const account = Account("alice");
|
|
env.fund(XRP(1000), account);
|
|
env.close();
|
|
|
|
// build tx
|
|
auto tx = invoke::invoke(account);
|
|
|
|
// verify hooks fee
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "16";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testOfferCancel(FeatureBitset features)
|
|
{
|
|
testcase("offer cancel w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testOfferCreate(FeatureBitset features)
|
|
{
|
|
testcase("offer create w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testPayment(FeatureBitset features)
|
|
{
|
|
testcase("payment w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
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), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
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), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
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), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
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), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "73022" : "73016";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
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), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "0" : "0";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
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), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testTicketCreate(FeatureBitset features)
|
|
{
|
|
testcase("ticket create w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
auto const account = Account("alice");
|
|
env.fund(XRP(1000), account);
|
|
env.close();
|
|
|
|
// build tx
|
|
auto tx = ticket::create(account, 2);
|
|
|
|
// verify hooks fee
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testTrustSet(FeatureBitset features)
|
|
{
|
|
testcase("trust set w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testURITokenBurnFee(FeatureBitset features)
|
|
{
|
|
testcase("uritoken burn w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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::burn(issuer, hexid);
|
|
|
|
// verify hooks fee
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testURITokenBuyFee(FeatureBitset features)
|
|
{
|
|
testcase("uritoken buy w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
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), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
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), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
void
|
|
testURITokenMintFee(FeatureBitset features)
|
|
{
|
|
testcase("uritoken mint w/ hook params");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
Env env{*this, network::makeNetworkConfig(21337), features};
|
|
|
|
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
|
|
std::string const feeResult =
|
|
env.current()->rules().enabled(fixXahauV1) ? "16" : "10";
|
|
testRPCCall(env, tx, feeResult);
|
|
}
|
|
|
|
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);
|
|
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:
|
|
void
|
|
run() override
|
|
{
|
|
using namespace test::jtx;
|
|
auto const sa = supported_amendments();
|
|
testWithFeats(sa);
|
|
testWithFeats(sa - fixXahauV1);
|
|
}
|
|
};
|
|
|
|
BEAST_DEFINE_TESTSUITE(BaseFee, app, ripple);
|
|
|
|
} // namespace test
|
|
} // namespace ripple
|