1#include <test/jtx/Account.h>
2#include <test/jtx/Env.h>
3#include <test/jtx/Env_ss.h>
4#include <test/jtx/amount.h>
5#include <test/jtx/balance.h>
6#include <test/jtx/check.h>
7#include <test/jtx/envconfig.h>
8#include <test/jtx/fee.h>
9#include <test/jtx/jtx_json.h>
10#include <test/jtx/noop.h>
11#include <test/jtx/offer.h>
12#include <test/jtx/owners.h>
13#include <test/jtx/pay.h>
14#include <test/jtx/require.h>
15#include <test/jtx/rpc.h>
16#include <test/jtx/seq.h>
17#include <test/jtx/sig.h>
18#include <test/jtx/tags.h>
19#include <test/jtx/ter.h>
21#include <xrpld/app/ledger/LedgerMaster.h>
23#include <xrpl/basics/CountedObject.h>
24#include <xrpl/basics/SHAMapHash.h>
25#include <xrpl/basics/StringUtilities.h>
26#include <xrpl/basics/base_uint.h>
27#include <xrpl/beast/unit_test/suite.h>
28#include <xrpl/config/Constants.h>
29#include <xrpl/json/json_reader.h>
30#include <xrpl/json/json_value.h>
31#include <xrpl/ledger/ApplyView.h>
32#include <xrpl/ledger/Ledger.h>
33#include <xrpl/ledger/OpenView.h>
34#include <xrpl/protocol/Indexes.h>
35#include <xrpl/protocol/KeyType.h>
36#include <xrpl/protocol/SField.h>
37#include <xrpl/protocol/STTx.h>
38#include <xrpl/protocol/SystemParameters.h>
39#include <xrpl/protocol/TER.h>
40#include <xrpl/protocol/TxFormats.h>
41#include <xrpl/protocol/XRPAmount.h>
42#include <xrpl/protocol/jss.h>
43#include <xrpl/tx/apply.h>
45#include <boost/asio/buffer.hpp>
67 auto const usd = gw[
"USD"];
68 env.
fund(
XRP(10000),
"alice", gw);
70 env(
offer(
"alice", usd(20),
XRP(10)),
72 { "OfferSequence" : 4 }
80 testcase(
"Account balance < fee destroys correct amount of XRP");
91 env.
app().config().fees.toFees(),
95 BEAST_EXPECT(closed->header().drops == expectedDrops);
97 auto const aliceXRP = 400;
98 auto const aliceAmount =
XRP(aliceXRP);
103 auto const jt = env.
jt(
pay(env.
master,
"alice", aliceAmount));
108 BEAST_EXPECT(result.applied);
112 expectedDrops -= next->fees().base;
113 BEAST_EXPECT(next->header().drops == expectedDrops);
117 auto balance = sle->getFieldAmount(sfBalance);
119 BEAST_EXPECT(balance == aliceAmount);
125 auto const jt = env.
jt(
noop(
"alice"),
Fee(expectedDrops),
Seq(2));
131 BEAST_EXPECT(result.applied);
138 auto balance = sle->getFieldAmount(sfBalance);
140 BEAST_EXPECT(balance ==
XRP(0));
143 BEAST_EXPECT(next->header().drops == expectedDrops);
149 testcase(
"Signing with a secp256r1 key should fail gracefully");
154 auto test256r1key = [&env](
Account const& acct) {
155 auto const baseFee = env.
current()->fees().base;
159 JTx jt = env.
jt(jsonNoOp);
165 "045d02995ec24988d9a2ae06a3733aa35ba0741e87527"
166 "ed12909b60bd458052c944b24cbf5893c3e5be321774e"
167 "5082e11c034b765861d0effbde87423f8476bb2c";
170 jt.
jv[
"SigningPubKey"] = secp256r1PubKey;
174 auto pubKeyBlob =
strUnHex(secp256r1PubKey);
176 secp256r1Sig->setFieldVL(sfSigningPubKey, *pubKeyBlob);
177 jt.
stx.reset(secp256r1Sig.release());
179 env(jt,
Rpc(
"invalidTransaction",
"fails local checks: Invalid signature."));
185 env.
fund(
XRP(10000), alice, becky);
194 testcase(
"Autofilled fee should use the escalated fee");
198 cfg->fees.referenceFee = 10;
203 auto const alice =
Account(
"alice");
204 env.fund(
XRP(100000), alice);
208 params[jss::fee_mult_max] = 5000;
213 for (
int i = 0; i < 5; ++i)
218 if (BEAST_EXPECT(tx))
220 BEAST_EXPECT(tx->getAccountID(sfAccount) == alice.id());
221 BEAST_EXPECT(tx->getTxnType() == ttACCOUNT_SET);
222 auto const fee = tx->getFieldAmount(sfFee);
223 BEAST_EXPECT(fee ==
drops(expectedFees[i]));
231 testcase(
"Fee escalation shouldn't allocate extreme memory");
234 using namespace std::chrono_literals;
246 env(
noop(env.master));
249 auto const start = clock_type::now();
251 BEAST_EXPECT(clock_type::now() - start < 1s);
258 using boost::asio::buffer;
262 R
"json({"command":"path_find","id":19,"subcommand":"create","source_account":"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh","destination_account":"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh","destination_amount":"1000000","source_currencies":[{"currency":"0000000000000000000000000000000000000000"},{"currency":"0000000000000000000000005553440000000000"},{"currency":"0000000000000000000000004254430000000000"},{"issuer":"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh","currency":"0000000000000000000000004254430000000000"},{"issuer":"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh","currency":"0000000000000000000000004254430000000000"},{"issuer":"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh","currency":"0000000000000000000000004555520000000000"},{"currency":"0000000000000000000000004554480000000000"},{"currency":"0000000000000000000000004A50590000000000"},{"issuer":"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh","currency":"000000000000000000000000434E590000000000"},{"currency":"0000000000000000000000004742490000000000"},{"issuer":"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh","currency":"0000000000000000000000004341440000000000"}]})json";
270 BEAST_EXPECT(jrReader.parse(jvRequest, buffers) && jvRequest.isObject());
276 testcase(
"Invalid Transaction Object ID Type");
284 env.
fund(
XRP(10'000), alice, bob);
289 if (BEAST_EXPECT(aliceIndex.isNonZero()))
301 if (!state.peekItem(bobIndex,
digest))
303 return digest.asUInt256();
308 for (
auto const& e : list)
310 result[e.first] = e.second;
316 if (BEAST_EXPECT(bobIndex.isNonZero()) && BEAST_EXPECT(
digest.has_value()))
326 using namespace std::string_literals;
328 beforeCounts.at(
"CachedView::hit"s) == afterCounts.at(
"CachedView::hit"s));
330 beforeCounts.at(
"CachedView::hitExpired"s) + 1 ==
331 afterCounts.at(
"CachedView::hitExpired"s));
333 beforeCounts.at(
"CachedView::miss"s) == afterCounts.at(
"CachedView::miss"s));
TestcaseT testcase
Memberspace for declaring test cases.
Unserialize a JSON document into a Value.
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
virtual Config & config()=0
std::unordered_set< uint256, beast::Uhash<> > features
static CountedObjects & getInstance() noexcept
std::vector< Entry > List
std::shared_ptr< Ledger const > getClosedLedger()
Writable ledger view that accumulates state and tx changes.
void apply(TxsRawView &to) const
Apply changes.
Rules controlling protocol behavior.
virtual LedgerMaster & getLedgerMaster()=0
virtual Family & getNodeFamily()=0
virtual TimeKeeper & getTimeKeeper()=0
virtual CachedSLEs & getCachedSLEs()=0
bool del(key_type const &key, bool valid)
time_point closeTime() const
Returns the predicted close time, in network time.
Immutable cryptographic account descriptor.
A transaction testing environment wrapper.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
void memoize(Account const &account)
Associate AccountID with account.
beast::Journal const journal
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Match the number of items in the account's owner directory.
Check a set of conditions.
Set the expected result code for a JTx The test will fail if the code doesn't match.
Set the regular signature on a JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
T emplace_back(T... args)
@ Object
object value (collection of name/value pairs).
Keylet account(AccountID const &id) noexcept
AccountID root.
json::Value cash(jtx::Account const &dest, uint256 const &checkId, STAmount const &amount)
Cash a check requiring that a specific amount be delivered.
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
XrpT const XRP
Converts to XRP Issue or STAmount.
json::Value noop(Account const &account)
The null transaction.
json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
ApplyResult apply(ServiceRegistry ®istry, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
CreateGenesisT const kCreateGenesis
constexpr XRPAmount kDropsPerXrp
Number of drops per 1 XRP.
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
bool isTesSuccess(TER x) noexcept
constexpr XRPAmount kInitialXrp
Configure the native currency.
static constexpr auto kTargetTxnInLedger
static constexpr auto kMinimumTxnInLedger
static constexpr auto kNormalConsensusIncreasePercent
static constexpr auto kMinimumTxnInLedgerStandalone
static constexpr auto kTransactionQueue
void run() override
Runs the suite.
void testFeeEscalationAutofill()
void testInvalidTxObjectIDType()
void testLowBalanceDestroy()
void testFeeEscalationExtremeConfig()
Execution context for applying a JSON transaction.
std::shared_ptr< STTx const > stx
Set the sequence number on a JTx.
Type used to specify DeliverMin for cashing a check.