Skip to content

Commit

Permalink
Add CFT direct payment
Browse files Browse the repository at this point in the history
* Add new Asset - variant of Currency and uint256
* Replace Currency with Asset in Issue
* Update STAmount for CFT
* Add CFTAmount
* Add DirectStepCFT
* Update strand generation for CFT
  • Loading branch information
gregtatcam committed Dec 4, 2023
1 parent 0556ae1 commit 022a12b
Show file tree
Hide file tree
Showing 33 changed files with 2,060 additions and 182 deletions.
1 change: 1 addition & 0 deletions Builds/CMake/RippledCore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ target_sources (rippled PRIVATE
src/ripple/app/paths/impl/AMMOffer.cpp
src/ripple/app/paths/impl/BookStep.cpp
src/ripple/app/paths/impl/DirectStep.cpp
src/ripple/app/paths/impl/DirectStepCFT.cpp
src/ripple/app/paths/impl/PaySteps.cpp
src/ripple/app/paths/impl/XRPEndpointStep.cpp
src/ripple/app/rdb/backend/detail/impl/Node.cpp
Expand Down
8 changes: 5 additions & 3 deletions src/ripple/app/ledger/OrderBookDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,12 @@ OrderBookDB::update(std::shared_ptr<ReadView const> const& ledger)
sle->getFieldH256(sfRootIndex) == sle->key())
{
Book book;

book.in.currency = sle->getFieldH160(sfTakerPaysCurrency);
// TODO update for CFT once supported in the offers
book.in.currency = static_cast<Currency>(
sle->getFieldH160(sfTakerPaysCurrency));
book.in.account = sle->getFieldH160(sfTakerPaysIssuer);
book.out.currency = sle->getFieldH160(sfTakerGetsCurrency);
book.out.currency = static_cast<Currency>(
sle->getFieldH160(sfTakerGetsCurrency));
book.out.account = sle->getFieldH160(sfTakerGetsIssuer);

allBooks[book.in].insert(book.out);
Expand Down
19 changes: 19 additions & 0 deletions src/ripple/app/paths/Flow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,25 @@ flow(
}

assert(!srcIsXRP && !dstIsXRP);
if (srcIssue.currency.isCFT())
{
assert(dstIssue.currency.isCFT());
return finishFlow(
sb,
srcIssue,
dstIssue,
flow<CFTAmount, CFTAmount>(
sb,
strands,
asDeliver.cft,
partialPayment,
offerCrossing,
limitQuality,
sendMax,
j,
ammContext,
flowDebugInfo));
}
return finishFlow(
sb,
srcIssue,
Expand Down
4 changes: 2 additions & 2 deletions src/ripple/app/paths/PathRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ PathRequest::parseJson(Json::Value const& jvParams)

convert_all_ = saDstAmount == STAmount(saDstAmount.issue(), 1u, 0, true);

if ((saDstAmount.getCurrency().isZero() &&
if ((saDstAmount.getCurrency().isXRP() &&
saDstAmount.getIssuer().isNonZero()) ||
(saDstAmount.getCurrency() == badCurrency()) ||
(!convert_all_ && saDstAmount <= beast::zero))
Expand All @@ -335,7 +335,7 @@ PathRequest::parseJson(Json::Value const& jvParams)

saSendMax.emplace();
if (!amountFromJsonNoThrow(*saSendMax, jvParams[jss::send_max]) ||
(saSendMax->getCurrency().isZero() &&
(saSendMax->getCurrency().isXRP() &&
saSendMax->getIssuer().isNonZero()) ||
(saSendMax->getCurrency() == badCurrency()) ||
(*saSendMax <= beast::zero &&
Expand Down
6 changes: 3 additions & 3 deletions src/ripple/app/paths/Pathfinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,7 @@ Pathfinder::addLink(
auto const& uEndCurrency = pathEnd.getCurrency();
auto const& uEndIssuer = pathEnd.getIssuerID();
auto const& uEndAccount = pathEnd.getAccountID();
bool const bOnXRP = uEndCurrency.isZero();
bool const bOnXRP = uEndCurrency.isXRP();

// Does pathfinding really need to get this to
// a gateway (the issuer of the destination amount)
Expand Down Expand Up @@ -1149,7 +1149,7 @@ Pathfinder::addLink(
{
STPath newPath(currentPath);

if (book.out.currency.isZero())
if (book.out.currency.isXRP())
{ // to XRP

// add the order book itself
Expand All @@ -1159,7 +1159,7 @@ Pathfinder::addLink(
xrpCurrency(),
xrpAccount());

if (mDstAmount.getCurrency().isZero())
if (mDstAmount.getCurrency().isXRP())
{
// destination is XRP, add account and path is
// complete
Expand Down
70 changes: 57 additions & 13 deletions src/ripple/app/paths/impl/AmountSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#ifndef RIPPLE_PATH_IMPL_AMOUNTSPEC_H_INCLUDED
#define RIPPLE_PATH_IMPL_AMOUNTSPEC_H_INCLUDED

#include <ripple/basics/CFTAmount.h>
#include <ripple/basics/IOUAmount.h>
#include <ripple/basics/XRPAmount.h>
#include <ripple/protocol/STAmount.h>
Expand All @@ -33,18 +34,22 @@ struct AmountSpec
explicit AmountSpec() = default;

bool native;
bool is_cft;
union
{
CFTAmount cft;
XRPAmount xrp;
IOUAmount iou = {};
};
std::optional<AccountID> issuer;
std::optional<Currency> currency;
std::optional<Asset> currency;

friend std::ostream&
operator<<(std::ostream& stream, AmountSpec const& amt)
{
if (amt.native)
if (amt.is_cft)
stream << to_string(amt.cft);
else if (amt.native)
stream << to_string(amt.xrp);
else
stream << to_string(amt.iou);
Expand All @@ -60,12 +65,14 @@ struct EitherAmount
{
#ifndef NDEBUG
bool native = false;
bool is_cft = false;
#endif

union
{
IOUAmount iou = {};
XRPAmount xrp;
CFTAmount cft;
};

EitherAmount() = default;
Expand All @@ -89,12 +96,22 @@ struct EitherAmount
#pragma GCC diagnostic pop
#endif

explicit EitherAmount(CFTAmount const& a) : cft(a)
{
#ifndef NDEBUG
is_cft = true;
#endif
}

explicit EitherAmount(AmountSpec const& a)
{
#ifndef NDEBUG
native = a.native;
is_cft = a.is_cft;
#endif
if (a.native)
if (a.is_cft)
cft = a.cft;
else if (a.native)
xrp = a.xrp;
else
iou = a.iou;
Expand All @@ -104,7 +121,9 @@ struct EitherAmount
friend std::ostream&
operator<<(std::ostream& stream, EitherAmount const& amt)
{
if (amt.native)
if (amt.is_cft)
stream << to_string(amt.cft);
else if (amt.native)
stream << to_string(amt.xrp);
else
stream << to_string(amt.iou);
Expand All @@ -125,18 +144,26 @@ template <>
inline IOUAmount&
get<IOUAmount>(EitherAmount& amt)
{
assert(!amt.native);
assert(!amt.native && !amt.is_cft);
return amt.iou;
}

template <>
inline XRPAmount&
get<XRPAmount>(EitherAmount& amt)
{
assert(amt.native);
assert(amt.native && !amt.is_cft);
return amt.xrp;
}

template <>
inline CFTAmount&
get<CFTAmount>(EitherAmount& amt)
{
assert(amt.is_cft && !amt.native);
return amt.cft;
}

template <class T>
T const&
get(EitherAmount const& amt)
Expand All @@ -149,18 +176,26 @@ template <>
inline IOUAmount const&
get<IOUAmount>(EitherAmount const& amt)
{
assert(!amt.native);
assert(!amt.native && !amt.is_cft);
return amt.iou;
}

template <>
inline XRPAmount const&
get<XRPAmount>(EitherAmount const& amt)
{
assert(amt.native);
assert(amt.native && !amt.is_cft);
return amt.xrp;
}

template <>
inline CFTAmount const&
get<CFTAmount>(EitherAmount const& amt)
{
assert(amt.is_cft && !amt.native);
return amt.cft;
}

inline AmountSpec
toAmountSpec(STAmount const& amt)
{
Expand All @@ -177,7 +212,10 @@ toAmountSpec(STAmount const& amt)
}
else
{
result.iou = IOUAmount(sMant, amt.exponent());
if (amt.isCFT())
result.cft = CFTAmount(sMant);
else
result.iou = IOUAmount(sMant, amt.exponent());
result.issuer = amt.issue().account;
result.currency = amt.issue().currency;
}
Expand All @@ -190,17 +228,23 @@ toEitherAmount(STAmount const& amt)
{
if (isXRP(amt))
return EitherAmount{amt.xrp()};
else if (amt.isCFT())
return EitherAmount{amt.cft()};
return EitherAmount{amt.iou()};
}

inline AmountSpec
toAmountSpec(EitherAmount const& ea, std::optional<Currency> const& c)
toAmountSpec(EitherAmount const& ea, std::optional<Asset> const& a)
{
AmountSpec r;
r.native = (!c || isXRP(*c));
r.currency = c;
r.native = (!a || isXRP(*a));
r.currency = a;
assert(ea.native == r.native);
if (r.native)
if (r.is_cft)
{
r.cft = ea.cft;
}
else if (r.native)
{
r.xrp = ea.xrp;
}
Expand Down
Loading

0 comments on commit 022a12b

Please sign in to comment.