2#include <test/jtx/PathSet.h> 
    4#include <xrpld/app/paths/AMMContext.h> 
    5#include <xrpld/app/paths/Flow.h> 
    6#include <xrpld/app/paths/detail/Steps.h> 
    7#include <xrpld/app/paths/detail/StrandFlow.h> 
    9#include <xrpl/basics/contract.h> 
   10#include <xrpl/basics/random.h> 
   11#include <xrpl/ledger/PaymentSandbox.h> 
   12#include <xrpl/protocol/Feature.h> 
   13#include <xrpl/protocol/jss.h> 
   40            for (
auto const& 
path : jv[jss::Paths])
 
   43                for (
auto const& pe : 
path)
 
   45                    if (pe.isMember(jss::account))
 
   48                            !pe.isMember(jss::currency) &&
 
   49                            !pe.isMember(jss::issuer));
 
   51                            *parseBase58<AccountID>(
 
   52                                pe[jss::account].asString()),
 
   57                        pe.isMember(jss::currency) && pe.isMember(jss::issuer))
 
   63                            issuer = *parseBase58<AccountID>(
 
   64                                pe[jss::issuer].asString());
 
   66                            assert(
isXRP(*parseBase58<AccountID>(
 
   67                                pe[jss::issuer].asString())));
 
   75                paths.emplace_back(std::move(p));
 
 
 
  119        jv[field.jsonName] = value;
 
 
  131        IOU const iou{peer, currency};
 
 
  164        IOU const iou{acc, currency};
 
 
 
  208        sstr << 
rate << 
" (" << q << 
")";
 
 
  212    template <
class Stream>
 
  216        stream << 
"Strand:\n";
 
  217        for (
auto const& step : strand)
 
  218            stream << 
"\n" << *step;
 
 
  263        auto compareClose = [](Quality 
const& q1, Quality 
const& q2) {
 
  266            constexpr double tolerance = 0.0000001;
 
  267            return relativeDistance(q1, q2) <= tolerance;
 
  270        for (
auto const& strand : sr.second)
 
  272            Quality 
const theoreticalQ = *qualityUpperBound(sb, strand);
 
  273            auto const f = flow<IOUAmount, IOUAmount>(
 
  274                sb, strand, IOUAmount(10, 0), IOUAmount(5, 0), dummyJ);
 
  275            BEAST_EXPECT(f.success);
 
  276            Quality 
const actualQ(f.out, f.in);
 
  277            if (actualQ != theoreticalQ && !compareClose(actualQ, theoreticalQ))
 
  279                BEAST_EXPECT(actualQ == theoreticalQ);  
 
  280                log << 
"\nAcutal != Theoretical\n";
 
  285            if (expectedQ && expectedQ != theoreticalQ &&
 
  286                !compareClose(*expectedQ, theoreticalQ))
 
  288                BEAST_EXPECT(expectedQ == theoreticalQ);  
 
  289                log << 
"\nExpected != Theoretical\n";
 
 
  333        int const numTestIterations = reqNumIterations.
value_or(250);
 
  344        for (
int i = 0; i < numTestIterations; ++i)
 
  349            auto const alice = 
Account(
"alice" + iterAsStr);
 
  350            auto const bob = 
Account(
"bob" + iterAsStr);
 
  351            auto const carol = 
Account(
"carol" + iterAsStr);
 
  352            auto const dan = 
Account(
"dan" + iterAsStr);
 
  355                numAccounts == 4, 
"Path is only correct for four accounts");
 
  356            path const accountsPath(accounts[1], accounts[2]);
 
  357            env.
fund(
XRP(10000), alice, bob, carol, dan);
 
  370                if (j == numAccounts)
 
  374                    env, accounts[ii], accounts[j], currency);
 
  376                    env, accounts[ii], accounts[j], currency);
 
  380            IOU const iou{accounts.back(), currency};
 
  382                pay(accounts.front(), accounts.back(), iou(paymentAmount)),
 
 
  405        int const numTestIterations = reqNumIterations.
value_or(100);
 
  419        for (
int i = 0; i < numTestIterations; ++i)
 
  422            auto const alice = 
Account(
"alice" + iterAsStr);
 
  423            auto const bob = 
Account(
"bob" + iterAsStr);
 
  424            auto const carol = 
Account(
"carol" + iterAsStr);
 
  425            auto const dan = 
Account(
"dan" + iterAsStr);
 
  426            auto const oscar = 
Account(
"oscar" + iterAsStr);  
 
  427            auto const USDB = bob[
"USD"];
 
  428            auto const EURC = carol[
"EUR"];
 
  431                {alice, bob, carol, dan, oscar}};
 
  436            path const bookPath(~EURC);
 
  438            env.
fund(
XRP(10000), alice, bob, carol, dan, oscar);
 
  441            for (
auto const& acc : accounts)
 
  444            for (
auto const& currency : {usdCurrency, eurCurrency})
 
  447                    env, alice, bob, currency);  
 
  449                    env, carol, dan, currency);  
 
  451                    env, oscar, bob, currency);  
 
  453                    env, oscar, carol, currency);  
 
  461            env(
offer(oscar, USDB(50), EURC(50)));
 
  465            IOU const srcIOU{bob, usdCurrency};
 
  466            IOU const dstIOU{carol, eurCurrency};
 
  468                pay(alice, dan, dstIOU(paymentAmount)),
 
  469                sendmax(srcIOU(100 * paymentAmount)),
 
 
  480        testcase(
"Relative quality distance");
 
  483                            int exponent = 0) -> Quality {
 
  489            return Quality{
one, v};
 
  492        BEAST_EXPECT(relativeDistance(toQuality(100), toQuality(100)) == 0);
 
  493        BEAST_EXPECT(relativeDistance(toQuality(100), toQuality(100, 1)) == 9);
 
  494        BEAST_EXPECT(relativeDistance(toQuality(100), toQuality(110)) == .1);
 
  496            relativeDistance(toQuality(100, 90), toQuality(110, 90)) == .1);
 
  498            relativeDistance(toQuality(100, 90), toQuality(110, 91)) == 10);
 
  500            relativeDistance(toQuality(100, 0), toQuality(100, 90)) == 1e90);
 
  506            relativeDistance(toQuality(102, 0), toQuality(101, 90)) >= 1e89);
 
 
  520                auto const r = stoi(s, &pos);
 
 
 
  536BEAST_DEFINE_TESTSUITE_PRIO(TheoreticalQuality, app, 
ripple, 3);
 
bool isMember(char const *key) const
Return true if the object has a member named key.
 
A generic endpoint for log messages.
 
static Sink & getNullSink()
Returns a Sink which does nothing.
 
log_os< char > log
Logging output stream.
 
testcase_t testcase
Memberspace for declaring test cases.
 
std::string const & arg() const
Return the argument associated with the runner.
 
Maintains AMM info per overall payment engine execution and individual iteration.
 
A wrapper which makes credits unavailable to balances.
 
Issue const & issue() const
 
void emplace_back(Args &&... args)
 
void setupTrustLine(jtx::Env &env, jtx::Account const &acc, jtx::Account const &peer, Currency const ¤cy)
 
std::uniform_real_distribution zeroOneDist_
 
void maybeInsertQuality(Json::Value &jv, QualityDirection qDir)
 
void maybeSetInitialBalance(jtx::Env &env, jtx::Account const &acc, jtx::Account const &peer, Currency const ¤cy)
 
void setInitialBalance(jtx::Env &env, jtx::Account const &acc, jtx::Account const &peer, Currency const ¤cy)
 
beast::xor_shift_engine engine_
 
static constexpr double probRedeem_
 
RandomAccountParams(std::uint32_t trustAmount=100, std::uint32_t initialBalance=50)
 
std::uint32_t const initialBalance_
 
std::uniform_real_distribution transferRateDist_
 
std::uniform_real_distribution qualityPercentDist_
 
void setupTrustLines(jtx::Env &env, jtx::Account const &acc1, jtx::Account const &acc2, Currency const ¤cy)
 
std::uint32_t const trustAmount_
 
static constexpr double probChangeDefault_
 
void maybeSetTransferRate(jtx::Env &env, jtx::Account const &acc)
 
void run() override
Runs the suite.
 
static std::string prettyQuality(Quality const &q)
 
void testBookStep(std::optional< int > const &reqNumIterations)
 
void testRelativeQDistance()
 
void testDirectStep(std::optional< int > const &reqNumIterations)
 
static void logStrand(Stream &stream, Strand const &strand)
 
void testCase(RippleCalcTestParams const &rcp, std::shared_ptr< ReadView const > closed, std::optional< Quality > const &expectedQ={})
 
Immutable cryptographic account descriptor.
 
A transaction testing environment.
 
Json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
 
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
 
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
 
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
 
Converts to IOU Issue or STAmount.
 
Set Paths, SendMax on a JTx.
 
Sets the SendMax on a JTx.
 
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
 
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
 
FeatureBitset testable_amendments()
 
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
 
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
 
XRP_t const XRP
Converts to XRP Issue or STAmount.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
bool isXRP(AccountID const &c)
 
std::optional< AccountID > parseBase58(std::string const &s)
Parse AccountID from checked, base58 string.
 
STAmount amountFromJson(SField const &name, Json::Value const &v)
 
constexpr std::uint32_t tfPartialPayment
 
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
 
constexpr std::uint32_t tfNoRippleDirect
 
std::pair< TER, std::vector< Strand > > toStrands(ReadView const &view, AccountID const &src, AccountID const &dst, Issue const &deliver, std::optional< Quality > const &limitQuality, std::optional< Issue > const &sendMax, STPathSet const &paths, bool addDefaultPath, bool ownerPaysTransferFee, OfferCrossing offerCrossing, AMMContext &ammContext, std::optional< uint256 > const &domainID, beast::Journal j)
Create a Strand for each specified path (including the default path, if indicated)
 
bool to_currency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
 
RippleCalcTestParams(Json::Value const &jv)
 
std::optional< STAmount > sendMax