21 #include <ripple/app/tx/applySteps.h>
22 #include <ripple/ledger/Directory.h>
23 #include <ripple/protocol/Feature.h>
24 #include <ripple/protocol/Indexes.h>
25 #include <ripple/protocol/jss.h>
26 #include <ripple/protocol/TxFlags.h>
38 0xA0, 0x02, 0x80, 0x00
43 0xA0, 0x25, 0x80, 0x20, 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14,
44 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, 0x27, 0xAE, 0x41, 0xE4,
45 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55,
52 0xA0, 0x05, 0x80, 0x03, 0x61, 0x61, 0x61
57 0xA0, 0x25, 0x80, 0x20, 0x98, 0x34, 0x87, 0x6D, 0xCF, 0xB0, 0x5C, 0xB1,
58 0x67, 0xA5, 0xC2, 0x49, 0x53, 0xEB, 0xA5, 0x8C, 0x4A, 0xC8, 0x9B, 0x1A,
59 0xDF, 0x57, 0xF2, 0x8F, 0x2F, 0x9D, 0x09, 0xAF, 0x10, 0x7E, 0xE8, 0xF0,
66 0xA0, 0x06, 0x80, 0x04, 0x6E, 0x69, 0x6B, 0x62
71 0xA0, 0x25, 0x80, 0x20, 0x6E, 0x4C, 0x71, 0x45, 0x30, 0xC0, 0xA4, 0x26,
72 0x8B, 0x3F, 0xA6, 0x3B, 0x1B, 0x60, 0x6F, 0x2D, 0x26, 0x4A, 0x2D, 0x85,
73 0x7B, 0xE8, 0xA0, 0x9C, 0x1D, 0xFD, 0x57, 0x0D, 0x15, 0x85, 0x8B, 0xD4,
174 jv[jss::TransactionType] = jss::EscrowCreate;
176 jv[jss::Account] = account.human();
177 jv[jss::Destination] = to.
human();
188 jv[jss::TransactionType] = jss::EscrowFinish;
190 jv[jss::Account] = account.human();
202 jv[jss::TransactionType] = jss::EscrowCancel;
204 jv[jss::Account] = account.human();
213 testcase (
"Enablement");
219 env.
fund(
XRP(5000),
"alice",
"bob");
223 auto const seq1 = env.
seq(
"alice");
228 env(
finish(
"bob",
"alice", seq1),
231 auto const seq2 = env.
seq(
"alice");
236 env(
cancel(
"bob",
"alice", seq2),
fee(1500));
246 testcase(
"Timing: Finish Only");
248 env.
fund(
XRP(5000),
"alice",
"bob");
252 auto const ts = env.
now() + 97s;
254 auto const seq = env.
seq(
"alice");
259 for ( ; env.
now() < ts; env.
close())
266 testcase(
"Timing: Cancel Only");
268 env.
fund(
XRP(5000),
"alice",
"bob");
272 auto const ts = env.
now() + 117s;
274 auto const seq = env.
seq(
"alice");
279 for ( ; env.
now() < ts; env.
close())
291 testcase(
"Timing: Finish and Cancel -> Finish");
293 env.
fund(
XRP(5000),
"alice",
"bob");
297 auto const fts = env.
now() + 117s;
298 auto const cts = env.
now() + 192s;
300 auto const seq = env.
seq(
"alice");
305 for ( ; env.
now() < fts; env.
close())
319 testcase(
"Timing: Finish and Cancel -> Cancel");
321 env.
fund(
XRP(5000),
"alice",
"bob");
325 auto const fts = env.
now() + 109s;
326 auto const cts = env.
now() + 184s;
328 auto const seq = env.
seq(
"alice");
333 for ( ; env.
now() < fts; env.
close())
341 for ( ; env.
now() < cts; env.
close())
363 auto const alice =
Account(
"alice");
364 auto const bob =
Account(
"bob");
366 env.
fund(
XRP(5000), alice, bob);
374 auto const seq = env.
seq(alice);
387 testcase (
"Disallow XRP");
396 env.
fund(
XRP(5000),
"bob",
"george");
406 env.
fund(
XRP(5000),
"bob",
"george");
419 testcase (
"Implied Finish Time (without fix1571)");
422 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
427 auto const seq1 = env.
seq(
"alice");
430 env(
finish(
"carol",
"alice", seq1),
fee(1500));
431 BEAST_EXPECT (env.
balance (
"bob") ==
XRP(5100));
437 auto const seq2 = env.
seq(
"alice");
443 BEAST_EXPECT (env.
balance (
"bob") ==
XRP(5200));
447 testcase (
"Implied Finish Time (with fix1571)");
450 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
458 auto const seq = env.
seq(
"alice");
464 BEAST_EXPECT (env.
balance (
"bob") ==
XRP(5100));
471 testcase (
"Failure Cases");
477 env.
fund(
XRP(5000),
"alice",
"bob");
501 env (
escrow(
"alice",
"carol",
XRP(-1000)),
535 auto const accountReserve =
drops(env.
current()->fees().reserve);
536 auto const accountIncrement =
drops(env.
current()->fees().increment);
538 env.
fund (accountReserve + accountIncrement +
XRP(50),
"daniel");
542 env.
fund (accountReserve + accountIncrement +
XRP(50),
"evan");
546 env.
fund (accountReserve,
"frank");
552 env.
fund (
XRP(5000),
"hannah");
553 auto const seq = env.
seq(
"hannah");
562 auto const seq = env.
seq(
"ivan");
582 env.
fund(
XRP(5000),
"alice",
"bob");
583 auto const seq = env.
seq(
"alice");
605 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
606 auto const seq = env.
seq(
"alice");
631 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
635 auto const seq = env.
seq(
"alice");
659 auto const baseFee = env.
current()->fees().base;
669 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
672 env(deposit::auth (
"bob",
"zelda"));
675 auto const seq = env.
seq(
"alice");
687 auto const baseFee = env.
current()->fees().base;
695 env.
fund(
XRP(5000),
"alice",
"bob");
696 auto const seq = env.
seq(
"alice");
727 env.
fund(
XRP(5000),
"alice",
"bob");
728 auto const seq = env.
seq(
"alice");
753 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
754 auto const seq = env.
seq(
"alice");
761 env(deposit::auth(
"alice",
"zelda"));
786 testcase (
"Escrow with CryptoConditions");
793 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
794 auto const seq = env.
seq(
"alice");
845 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
846 auto const seq = env.
seq(
"alice");
860 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
862 auto const seq = env.
seq(
"alice");
878 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
884 auto const p = v.
data();
885 auto const s = v.
size();
887 auto const ts = env.
now() + 1s;
906 auto const seq = env.
seq(
"alice");
917 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
923 auto const cp = cv.
data();
924 auto const cs = cv.
size();
930 auto const fp = fv.
data();
931 auto const fs = fv.
size();
933 auto const ts = env.
now() + 1s;
952 auto const seq = env.
seq(
"alice");
1000 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
1005 auto const seq = env.
seq(
"alice");
1006 env(
escrow(
"alice",
"carol",
XRP(1000)),
1030 env.
fund(
XRP(5000),
"alice",
"bob");
1034 0xA2, 0x2B, 0x80, 0x20, 0x42, 0x4A, 0x70, 0x49, 0x49, 0x52,
1035 0x92, 0x67, 0xB6, 0x21, 0xB3, 0xD7, 0x91, 0x19, 0xD7, 0x29,
1036 0xB2, 0x38, 0x2C, 0xED, 0x8B, 0x29, 0x6C, 0x3C, 0x02, 0x8F,
1037 0xA9, 0x7D, 0x35, 0x0F, 0x6D, 0x07, 0x81, 0x03, 0x06, 0x34,
1038 0xD2, 0x82, 0x02, 0x03, 0xC8
1051 using namespace jtx;
1054 auto const alice =
Account(
"alice");
1055 auto const bruce =
Account(
"bruce");
1056 auto const carol =
Account(
"carol");
1059 testcase (
"Metadata to self");
1062 env.
fund(
XRP(5000), alice, bruce, carol);
1063 auto const aseq = env.
seq(alice);
1064 auto const bseq = env.
seq(bruce);
1095 env(
finish(alice, alice, aseq));
1111 env(
cancel(bruce, bruce, bseq));
1123 testcase (
"Metadata to other");
1126 env.
fund(
XRP(5000), alice, bruce, carol);
1127 auto const aseq = env.
seq(alice);
1128 auto const bseq = env.
seq(bruce);
1162 env(
finish(alice, alice, aseq));
1181 env(
cancel(bruce, bruce, bseq));
1203 testcase (
"Consequences");
1205 using namespace jtx;
1214 auto const jtx = env.
jt(
escrow(
"alice",
"carol",
XRP(1000)),
1221 BEAST_EXPECT(conseq.fee ==
drops(10));
1222 BEAST_EXPECT(conseq.potentialSpend ==
XRP(1000));
1226 auto const jtx = env.
jt(
cancel(
"bob",
"alice", 3),
seq(1),
fee(10));
1232 BEAST_EXPECT(conseq.fee ==
drops(10));
1233 BEAST_EXPECT(conseq.potentialSpend ==
XRP(0));
1237 auto const jtx = env.
jt(
finish(
"bob",
"alice", 3),
seq(1),
fee(10));
1243 BEAST_EXPECT(conseq.fee ==
drops(10));
1244 BEAST_EXPECT(conseq.potentialSpend ==
XRP(0));
const XRP_t XRP
Converts to XRP Issue or STAmount.
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
const_iterator begin() const
static Json::Value escrow(jtx::Account const &account, jtx::Account const &to, STAmount const &amount)
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
const std::array< std::uint8_t, 39 > cb3
Set the expected result code for a JTx The test will fail if the code doesn't match.
void require(Args const &... args)
Check a set of requirements.
An immutable linear range of bytes.
Json::Value getJson(JsonOptions) const override
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
const uint256 featureDepositAuth
const std::array< std::uint8_t, 8 > fb3
@ normal
Moves currency around, creates offers, etc.
static Json::Value finish(jtx::Account const &account, jtx::Account const &from, std::uint32_t seq)
std::string const & human() const
Returns the human readable public key.
const beast::Journal journal
const std::uint32_t asfDepositAuth
const std::uint32_t asfDisallowXRP
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
PreflightResult preflight(Application &app, Rules const &rules, STTx const &tx, ApplyFlags flags, beast::Journal j)
Gate a transaction based on static information.
void testMetaAndOwnership()
const SF_U32 sfOwnerCount(access, STI_UINT32, 13, "OwnerCount")
const Json::StaticString jsonName
const SF_U32 sfFinishAfter(access, STI_UINT32, 37, "FinishAfter")
static Json::Value cancel(jtx::Account const &account, jtx::Account const &from, std::uint32_t seq)
NetClock::time_point value_
const SF_U32 sfDestinationTag(access, STI_UINT32, 14, "DestinationTag")
Set the source tag on a JTx.
const std::array< std::uint8_t, 39 > cb2
Set the "FinishAfter" time tag on a JTx.
const SF_Blob sfFulfillment(access, STI_VL, 16, "Fulfillment")
T time_since_epoch(T... args)
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
const SF_Account sfOwner(access, STI_ACCOUNT, 2, "Owner")
void operator()(jtx::Env &, jtx::JTx &jt) const
condition(std::array< std::uint8_t, N > c)
Set the "CancelAfter" time tag on a JTx.
Execution context for applying a JSON transaction.
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Keylet ownerDir(AccountID const &id)
The root page of an account's directory.
Keylet escrow(AccountID const &source, std::uint32_t seq)
An escrow entry.
fulfillment(Slice condition)
finish_time(NetClock::time_point const &value)
const std::array< std::uint8_t, 39 > cb1
FeatureBitset supported_amendments()
void operator()(jtx::Env &, jtx::JTx &jt) const
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
const SF_U32 sfSourceTag(access, STI_UINT32, 3, "SourceTag")
const std::uint32_t tfUniversal
const std::uint32_t asfRequireDest
Set the sequence number on a JTx.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
TxConsequences calculateConsequences(PreflightResult const &preflightResult)
Determine the XRP balance consequences if a transaction consumes the maximum XRP allowed.
NetClock::time_point now()
Returns the current Ripple Network Time.
const SF_U32 sfOfferSequence(access, STI_UINT32, 25, "OfferSequence")
void close(NetClock::time_point closeTime, boost::optional< std::chrono::milliseconds > consensusDelay=boost::none)
Close and advance the ledger.
void operator()(jtx::Env &, jtx::JTx &jt) const
fulfillment(std::array< std::uint8_t, N > f)
const std::array< std::uint8_t, 4 > fb1
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
const std::array< std::uint8_t, 7 > fb2
const SF_Blob sfCondition(access, STI_VL, 17, "Condition")
const SF_U8 sfTransactionResult(access, STI_UINT8, 3, "TransactionResult")
@ tecINSUFFICIENT_RESERVE
Set the destination tag on a JTx.
void testEscrowConditions()
Immutable cryptographic account descriptor.
std::string strHex(FwdIt begin, FwdIt end)
cancel_time(NetClock::time_point const &value)
const_iterator end() const
void operator()(jtx::Env &, jtx::JTx &jt) const
void memoize(Account const &account)
Associate AccountID with account.
NetClock::time_point value_
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
const SF_U32 sfCancelAfter(access, STI_UINT32, 36, "CancelAfter")
A transaction testing environment.
@ tecCRYPTOCONDITION_ERROR