Skip to content

Commit c1e4bfb

Browse files
committed
Introduce AMM support (XLS-30d)
1 parent 67cfbf5 commit c1e4bfb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+8790
-23
lines changed

Builds/CMake/RippledCore.cmake

+14
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ target_sources (xrpl_core PRIVATE
8181
src/ripple/protocol/impl/LedgerFormats.cpp
8282
src/ripple/protocol/impl/PublicKey.cpp
8383
src/ripple/protocol/impl/Quality.cpp
84+
src/ripple/protocol/impl/QualityFunction.cpp
8485
src/ripple/protocol/impl/Rate2.cpp
8586
src/ripple/protocol/impl/Rules.cpp
8687
src/ripple/protocol/impl/SField.cpp
@@ -212,6 +213,7 @@ install (
212213
src/ripple/protocol/Protocol.h
213214
src/ripple/protocol/PublicKey.h
214215
src/ripple/protocol/Quality.h
216+
src/ripple/protocol/QualityFunction.h
215217
src/ripple/protocol/Rate.h
216218
src/ripple/protocol/Rules.h
217219
src/ripple/protocol/SField.h
@@ -376,6 +378,8 @@ target_sources (rippled PRIVATE
376378
src/ripple/app/reporting/ReportingETL.cpp
377379
src/ripple/app/reporting/ETLSource.cpp
378380
src/ripple/app/reporting/P2pProxy.cpp
381+
src/ripple/app/misc/impl/AMM.cpp
382+
src/ripple/app/misc/impl/AMM_formulae.cpp
379383
src/ripple/app/misc/CanonicalTXSet.cpp
380384
src/ripple/app/misc/FeeVoteImpl.cpp
381385
src/ripple/app/misc/HashRouter.cpp
@@ -401,6 +405,7 @@ target_sources (rippled PRIVATE
401405
src/ripple/app/paths/RippleCalc.cpp
402406
src/ripple/app/paths/RippleLineCache.cpp
403407
src/ripple/app/paths/TrustLine.cpp
408+
src/ripple/app/paths/impl/AMMLiquidity.cpp
404409
src/ripple/app/paths/impl/BookStep.cpp
405410
src/ripple/app/paths/impl/DirectStep.cpp
406411
src/ripple/app/paths/impl/PaySteps.cpp
@@ -417,6 +422,11 @@ target_sources (rippled PRIVATE
417422
src/ripple/app/rdb/impl/UnitaryShard.cpp
418423
src/ripple/app/rdb/impl/Vacuum.cpp
419424
src/ripple/app/rdb/impl/Wallet.cpp
425+
src/ripple/app/tx/impl/AMMBid.cpp
426+
src/ripple/app/tx/impl/AMMCreate.cpp
427+
src/ripple/app/tx/impl/AMMDeposit.cpp
428+
src/ripple/app/tx/impl/AMMVote.cpp
429+
src/ripple/app/tx/impl/AMMWithdraw.cpp
420430
src/ripple/app/tx/impl/ApplyContext.cpp
421431
src/ripple/app/tx/impl/BookTip.cpp
422432
src/ripple/app/tx/impl/CancelCheck.cpp
@@ -582,6 +592,7 @@ target_sources (rippled PRIVATE
582592
src/ripple/rpc/handlers/AccountObjects.cpp
583593
src/ripple/rpc/handlers/AccountOffers.cpp
584594
src/ripple/rpc/handlers/AccountTx.cpp
595+
src/ripple/rpc/handlers/AMMInfo.cpp
585596
src/ripple/rpc/handlers/BlackList.cpp
586597
src/ripple/rpc/handlers/BookOffers.cpp
587598
src/ripple/rpc/handlers/CanDelete.cpp
@@ -686,6 +697,7 @@ if (tests)
686697
src/test/app/AccountDelete_test.cpp
687698
src/test/app/AccountTxPaging_test.cpp
688699
src/test/app/AmendmentTable_test.cpp
700+
src/test/app/AMM_test.cpp
689701
src/test/app/Check_test.cpp
690702
src/test/app/CrossingLimits_test.cpp
691703
src/test/app/DeliverMin_test.cpp
@@ -825,6 +837,7 @@ if (tests)
825837
src/test/jtx/Env_test.cpp
826838
src/test/jtx/WSClient_test.cpp
827839
src/test/jtx/impl/Account.cpp
840+
src/test/jtx/impl/AMM.cpp
828841
src/test/jtx/impl/Env.cpp
829842
src/test/jtx/impl/JSONRPCClient.cpp
830843
src/test/jtx/impl/ManualTimeKeeper.cpp
@@ -943,6 +956,7 @@ if (tests)
943956
src/test/rpc/AccountSet_test.cpp
944957
src/test/rpc/AccountTx_test.cpp
945958
src/test/rpc/AmendmentBlocked_test.cpp
959+
src/test/rpc/AMMInfo_test.cpp
946960
src/test/rpc/Book_test.cpp
947961
src/test/rpc/DepositAuthorized_test.cpp
948962
src/test/rpc/DeliveredAmount_test.cpp

Builds/levelization/results/loops.txt

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ Loop: ripple.nodestore ripple.overlay
4343
Loop: ripple.overlay ripple.rpc
4444
ripple.rpc ~= ripple.overlay
4545

46+
Loop: test.jtx test.rpc
47+
test.rpc > test.jtx
48+
4649
Loop: test.jtx test.toplevel
4750
test.toplevel > test.jtx
4851

Builds/levelization/results/ordering.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ test.jtx > ripple.json
143143
test.jtx > ripple.ledger
144144
test.jtx > ripple.net
145145
test.jtx > ripple.protocol
146+
test.jtx > ripple.rpc
146147
test.jtx > ripple.server
147148
test.ledger > ripple.app
148149
test.ledger > ripple.basics
@@ -204,7 +205,6 @@ test.rpc > ripple.overlay
204205
test.rpc > ripple.protocol
205206
test.rpc > ripple.resource
206207
test.rpc > ripple.rpc
207-
test.rpc > test.jtx
208208
test.rpc > test.nodestore
209209
test.rpc > test.toplevel
210210
test.server > ripple.app

src/ripple/app/ledger/OrderBookDB.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <ripple/app/ledger/LedgerMaster.h>
2121
#include <ripple/app/ledger/OrderBookDB.h>
2222
#include <ripple/app/main/Application.h>
23+
#include <ripple/app/misc/AMM.h>
2324
#include <ripple/app/misc/NetworkOPs.h>
2425
#include <ripple/basics/Log.h>
2526
#include <ripple/core/Config.h>
@@ -93,7 +94,7 @@ OrderBookDB::update(std::shared_ptr<ReadView const> const& ledger)
9394

9495
JLOG(j_.debug()) << "Beginning update (" << ledger->seq() << ")";
9596

96-
// walk through the entire ledger looking for orderbook entries
97+
// walk through the entire ledger looking for orderbook/AMM entries
9798
int cnt = 0;
9899

99100
try
@@ -126,6 +127,20 @@ OrderBookDB::update(std::shared_ptr<ReadView const> const& ledger)
126127

127128
++cnt;
128129
}
130+
else if (sle->getType() == ltAMM)
131+
{
132+
auto const [issue1, issue2] = getTokensIssue(*sle);
133+
auto addBook = [&](Issue const& in, Issue const& out) {
134+
allBooks[in].insert(out);
135+
136+
if (isXRP(out))
137+
xrpBooks.insert(in);
138+
139+
++cnt;
140+
};
141+
addBook(issue1, issue2);
142+
addBook(issue2, issue1);
143+
}
129144
}
130145
}
131146
catch (SHAMapMissingNode const& mn)

src/ripple/app/misc/AMM.h

+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
//------------------------------------------------------------------------------
2+
/*
3+
This file is part of rippled: https://github.com/ripple/rippled
4+
Copyright (c) 2022 Ripple Labs Inc.
5+
6+
Permission to use, copy, modify, and/or distribute this software for any
7+
purpose with or without fee is hereby granted, provided that the above
8+
copyright notice and this permission notice appear in all copies.
9+
10+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13+
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17+
*/
18+
//==============================================================================
19+
#ifndef RIPPLE_APP_MISC_AMM_H_INLCUDED
20+
#define RIPPLE_APP_MISC_AMM_H_INLCUDED
21+
22+
#include <ripple/beast/utility/Journal.h>
23+
#include <ripple/protocol/Quality.h>
24+
#include <ripple/protocol/STAmount.h>
25+
#include <ripple/protocol/STArray.h>
26+
#include <ripple/protocol/STLedgerEntry.h>
27+
#include <ripple/protocol/TER.h>
28+
#include <ripple/protocol/TxFlags.h>
29+
#include <ripple/protocol/digest.h>
30+
31+
namespace ripple {
32+
33+
class ReadView;
34+
class ApplyView;
35+
class Sandbox;
36+
class STLedgerEntry;
37+
class NetClock;
38+
class STObject;
39+
class Rules;
40+
41+
/** Calculate AMM account ID.
42+
*/
43+
template <typename... Args>
44+
AccountID
45+
calcAccountID(Args const&... args)
46+
{
47+
ripesha_hasher rsh;
48+
auto hash = sha512Half(args...);
49+
rsh(hash.data(), hash.size());
50+
return AccountID{static_cast<ripesha_hasher::result_type>(rsh)};
51+
}
52+
53+
/** Calculate AMM group hash. The ltAMM object
54+
* contains all AMM's for the same issues.
55+
*/
56+
uint256
57+
calcAMMGroupHash(Issue const& issue1, Issue const& issue2);
58+
59+
/** Calculate Liquidity Provider Token (LPT) Currency.
60+
*/
61+
Currency
62+
calcLPTCurrency(AccountID const& ammAccountID);
63+
64+
/** Calculate LPT Issue.
65+
*/
66+
Issue
67+
calcLPTIssue(AccountID const& ammAccountID);
68+
69+
/** Get AMM pool balances.
70+
*/
71+
std::pair<STAmount, STAmount>
72+
ammPoolHolds(
73+
ReadView const& view,
74+
AccountID const& ammAccountID,
75+
Issue const& issue1,
76+
Issue const& issue2,
77+
beast::Journal const j);
78+
79+
/** Get AMM pool and LP token balances. If both optIssue are
80+
* provided then they are used as the AMM token pair issues.
81+
* Otherwise the missing issues are fetched from ammSle.
82+
*/
83+
std::tuple<STAmount, STAmount, STAmount>
84+
ammHolds(
85+
ReadView const& view,
86+
SLE const& ammSle,
87+
std::optional<Issue> const& optIssue1,
88+
std::optional<Issue> const& optIssue2,
89+
beast::Journal const j);
90+
91+
/** Get the balance of LP tokens.
92+
*/
93+
STAmount
94+
lpHolds(
95+
ReadView const& view,
96+
AccountID const& ammAccountID,
97+
AccountID const& lpAccount,
98+
beast::Journal const j);
99+
100+
/** Validate the amount.
101+
* If zero is false and amount is beast::zero then invalid amount.
102+
* Return error code if invalid amount.
103+
*/
104+
std::optional<TEMcodes>
105+
invalidAmount(std::optional<STAmount> const& a, bool zero = false);
106+
107+
/** Check if the line is frozen from the issuer.
108+
*/
109+
bool
110+
isFrozen(ReadView const& view, std::optional<STAmount> const& a);
111+
112+
/** Get AMM SLE and verify that the AMM account exists.
113+
* Return null if SLE not found or AMM account doesn't exist.
114+
*/
115+
std::shared_ptr<STLedgerEntry const>
116+
getAMMSle(ReadView const& view, uint256 ammID);
117+
118+
std::shared_ptr<STLedgerEntry>
119+
getAMMSle(Sandbox& view, uint256 ammID);
120+
121+
/** Check if the account requires authorization.
122+
* Return true if issuer's account, account, and trust line exist
123+
* and the account requires authorization.
124+
*/
125+
bool
126+
requireAuth(ReadView const& view, Issue const& issue, AccountID const& account);
127+
128+
/** Get AMM trading fee for the given account. The fee is discounted
129+
* if the account is the auction slot owner or one of the slot's authorized
130+
* accounts.
131+
*/
132+
std::uint16_t
133+
getTradingFee(SLE const& ammSle, AccountID const& account);
134+
135+
/** Get Issue from sfToken1/sfToken2 fields.
136+
*/
137+
std::pair<Issue, Issue>
138+
getTokensIssue(SLE const& ammSle);
139+
140+
/** Send w/o fees. Either from or to must be AMM account.
141+
*/
142+
TER
143+
ammSend(
144+
ApplyView& view,
145+
AccountID const& from,
146+
AccountID const& to,
147+
STAmount const& amount,
148+
beast::Journal j);
149+
150+
/** Get time slot of the auction slot.
151+
*/
152+
std::uint16_t
153+
timeSlot(NetClock::time_point const& clock, STObject const& auctionSlot);
154+
155+
bool
156+
ammRequiredAmendments(Rules const&);
157+
158+
} // namespace ripple
159+
160+
#endif // RIPPLE_APP_MISC_AMM_H_INLCUDED

0 commit comments

Comments
 (0)