rippled
AMMCreate.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2023 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 
20 #include <ripple/app/tx/impl/AMMCreate.h>
21 
22 #include <ripple/app/ledger/OrderBookDB.h>
23 #include <ripple/app/misc/AMMHelpers.h>
24 #include <ripple/app/misc/AMMUtils.h>
25 #include <ripple/ledger/Sandbox.h>
26 #include <ripple/ledger/View.h>
27 #include <ripple/protocol/AMMCore.h>
28 #include <ripple/protocol/Feature.h>
29 #include <ripple/protocol/STAccount.h>
30 #include <ripple/protocol/STIssue.h>
31 #include <ripple/protocol/TxFlags.h>
32 
33 namespace ripple {
34 
35 NotTEC
37 {
38  if (!ammEnabled(ctx.rules))
39  return temDISABLED;
40 
41  if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
42  return ret;
43 
44  if (ctx.tx.getFlags() & tfUniversalMask)
45  {
46  JLOG(ctx.j.debug()) << "AMM Instance: invalid flags.";
47  return temINVALID_FLAG;
48  }
49 
50  auto const amount = ctx.tx[sfAmount];
51  auto const amount2 = ctx.tx[sfAmount2];
52 
53  if (amount.issue() == amount2.issue())
54  {
55  JLOG(ctx.j.debug())
56  << "AMM Instance: tokens can not have the same currency/issuer.";
57  return temBAD_AMM_TOKENS;
58  }
59 
60  if (auto const err = invalidAMMAmount(amount))
61  {
62  JLOG(ctx.j.debug()) << "AMM Instance: invalid asset1 amount.";
63  return err;
64  }
65 
66  if (auto const err = invalidAMMAmount(amount2))
67  {
68  JLOG(ctx.j.debug()) << "AMM Instance: invalid asset2 amount.";
69  return err;
70  }
71 
73  {
74  JLOG(ctx.j.debug()) << "AMM Instance: invalid trading fee.";
75  return temBAD_FEE;
76  }
77 
78  return preflight2(ctx);
79 }
80 
82 AMMCreate::calculateBaseFee(ReadView const& view, STTx const& tx)
83 {
84  // The fee required for AMMCreate is one owner reserve.
85  return view.fees().increment;
86 }
87 
88 TER
90 {
91  auto const accountID = ctx.tx[sfAccount];
92  auto const amount = ctx.tx[sfAmount];
93  auto const amount2 = ctx.tx[sfAmount2];
94 
95  // Check if AMM already exists for the token pair
96  if (auto const ammKeylet = keylet::amm(amount.issue(), amount2.issue());
97  ctx.view.read(ammKeylet))
98  {
99  JLOG(ctx.j.debug()) << "AMM Instance: ltAMM already exists.";
100  return tecDUPLICATE;
101  }
102 
103  if (auto const ter = requireAuth(ctx.view, amount.issue(), accountID);
104  ter != tesSUCCESS)
105  {
106  JLOG(ctx.j.debug())
107  << "AMM Instance: account is not authorized, " << amount.issue();
108  return ter;
109  }
110 
111  if (auto const ter = requireAuth(ctx.view, amount2.issue(), accountID);
112  ter != tesSUCCESS)
113  {
114  JLOG(ctx.j.debug())
115  << "AMM Instance: account is not authorized, " << amount2.issue();
116  return ter;
117  }
118 
119  // Globally or individually frozen
120  if (isFrozen(ctx.view, accountID, amount.issue()) ||
121  isFrozen(ctx.view, accountID, amount2.issue()))
122  {
123  JLOG(ctx.j.debug()) << "AMM Instance: involves frozen asset.";
124  return tecFROZEN;
125  }
126 
127  auto noDefaultRipple = [](ReadView const& view, Issue const& issue) {
128  if (isXRP(issue))
129  return false;
130 
131  if (auto const issuerAccount =
132  view.read(keylet::account(issue.account)))
133  return (issuerAccount->getFlags() & lsfDefaultRipple) == 0;
134 
135  return false;
136  };
137 
138  if (noDefaultRipple(ctx.view, amount.issue()) ||
139  noDefaultRipple(ctx.view, amount2.issue()))
140  {
141  JLOG(ctx.j.debug()) << "AMM Instance: DefaultRipple not set";
142  return terNO_RIPPLE;
143  }
144 
145  // Check the reserve for LPToken trustline
146  STAmount const xrpBalance = xrpLiquid(ctx.view, accountID, 1, ctx.j);
147  // Insufficient reserve
148  if (xrpBalance <= beast::zero)
149  {
150  JLOG(ctx.j.debug()) << "AMM Instance: insufficient reserves";
151  return tecINSUF_RESERVE_LINE;
152  }
153 
154  auto insufficientBalance = [&](STAmount const& asset) {
155  if (isXRP(asset))
156  return xrpBalance < asset;
157  return accountID != asset.issue().account &&
158  accountHolds(
159  ctx.view,
160  accountID,
161  asset.issue(),
162  FreezeHandling::fhZERO_IF_FROZEN,
163  ctx.j) < asset;
164  };
165 
166  if (insufficientBalance(amount) || insufficientBalance(amount2))
167  {
168  JLOG(ctx.j.debug())
169  << "AMM Instance: insufficient funds, " << amount << " " << amount2;
170  return tecUNFUNDED_AMM;
171  }
172 
173  auto isLPToken = [&](STAmount const& amount) -> bool {
174  if (auto const sle =
175  ctx.view.read(keylet::account(amount.issue().account)))
176  return sle->isFieldPresent(sfAMMID);
177  return false;
178  };
179 
180  if (isLPToken(amount) || isLPToken(amount2))
181  {
182  JLOG(ctx.j.debug()) << "AMM Instance: can't create with LPTokens "
183  << amount << " " << amount2;
184  return tecAMM_INVALID_TOKENS;
185  }
186 
187  // Disallow AMM if the issuer has clawback enabled
188  auto clawbackDisabled = [&](Issue const& issue) -> TER {
189  if (isXRP(issue))
190  return tesSUCCESS;
191  if (auto const sle = ctx.view.read(keylet::account(issue.account));
192  !sle)
193  return tecINTERNAL;
194  else if (sle->getFlags() & lsfAllowTrustLineClawback)
195  return tecNO_PERMISSION;
196  return tesSUCCESS;
197  };
198 
199  if (auto const ter = clawbackDisabled(amount.issue()); ter != tesSUCCESS)
200  return ter;
201  return clawbackDisabled(amount2.issue());
202 }
203 
206  ApplyContext& ctx_,
207  Sandbox& sb,
208  AccountID const& account_,
209  beast::Journal j_)
210 {
211  auto const amount = ctx_.tx[sfAmount];
212  auto const amount2 = ctx_.tx[sfAmount2];
213 
214  auto const ammKeylet = keylet::amm(amount.issue(), amount2.issue());
215 
216  // Mitigate same account exists possibility
217  auto const ammAccount = [&]() -> Expected<AccountID, TER> {
218  std::uint16_t constexpr maxAccountAttempts = 256;
219  for (auto p = 0; p < maxAccountAttempts; ++p)
220  {
221  auto const ammAccount =
222  ammAccountID(p, sb.info().parentHash, ammKeylet.key);
223  if (!sb.read(keylet::account(ammAccount)))
224  return ammAccount;
225  }
226  return Unexpected(tecDUPLICATE);
227  }();
228 
229  // AMM account already exists (should not happen)
230  if (!ammAccount)
231  {
232  JLOG(j_.error()) << "AMM Instance: AMM already exists.";
233  return {ammAccount.error(), false};
234  }
235 
236  // LP Token already exists. (should not happen)
237  auto const lptIss = ammLPTIssue(
238  amount.issue().currency, amount2.issue().currency, *ammAccount);
239  if (sb.read(keylet::line(*ammAccount, lptIss)))
240  {
241  JLOG(j_.error()) << "AMM Instance: LP Token already exists.";
242  return {tecDUPLICATE, false};
243  }
244 
245  // Create AMM Root Account.
246  auto sleAMMRoot = std::make_shared<SLE>(keylet::account(*ammAccount));
247  sleAMMRoot->setAccountID(sfAccount, *ammAccount);
248  sleAMMRoot->setFieldAmount(sfBalance, STAmount{});
249  std::uint32_t const seqno{
251  ? ctx_.view().seq()
252  : 1};
253  sleAMMRoot->setFieldU32(sfSequence, seqno);
254  // Ignore reserves requirement, disable the master key, allow default
255  // rippling (AMM LPToken can be used as a token in another AMM, which must
256  // support payments and offer crossing), and enable deposit authorization to
257  // prevent payments into AMM.
258  // Note, that the trustlines created by AMM have 0 credit limit.
259  // This prevents shifting the balance between accounts via AMM,
260  // or sending unsolicited LPTokens. This is a desired behavior.
261  // A user can only receive LPTokens through affirmative action -
262  // either an AMMDeposit, TrustSet, crossing an offer, etc.
263  sleAMMRoot->setFieldU32(
265  // Link the root account and AMM object
266  sleAMMRoot->setFieldH256(sfAMMID, ammKeylet.key);
267  sb.insert(sleAMMRoot);
268 
269  // Calculate initial LPT balance.
270  auto const lpTokens = ammLPTokens(amount, amount2, lptIss);
271 
272  // Create ltAMM
273  auto ammSle = std::make_shared<SLE>(ammKeylet);
274  ammSle->setAccountID(sfAccount, *ammAccount);
275  ammSle->setFieldAmount(sfLPTokenBalance, lpTokens);
276  auto const& [issue1, issue2] = std::minmax(amount.issue(), amount2.issue());
277  ammSle->setFieldIssue(sfAsset, STIssue{sfAsset, issue1});
278  ammSle->setFieldIssue(sfAsset2, STIssue{sfAsset2, issue2});
279  // AMM creator gets the auction slot and the voting slot.
281  ctx_.view(), ammSle, account_, lptIss, ctx_.tx[sfTradingFee]);
282  sb.insert(ammSle);
283 
284  // Send LPT to LP.
285  auto res = accountSend(sb, *ammAccount, account_, lpTokens, ctx_.journal);
286  if (res != tesSUCCESS)
287  {
288  JLOG(j_.debug()) << "AMM Instance: failed to send LPT " << lpTokens;
289  return {res, false};
290  }
291 
292  auto sendAndTrustSet = [&](STAmount const& amount) -> TER {
293  if (auto const res = accountSend(
294  sb,
295  account_,
296  *ammAccount,
297  amount,
298  ctx_.journal,
300  return res;
301  // Set AMM flag on AMM trustline
302  if (!isXRP(amount))
303  {
304  if (SLE::pointer sleRippleState =
305  sb.peek(keylet::line(*ammAccount, amount.issue()));
306  !sleRippleState)
307  return tecINTERNAL;
308  else
309  {
310  auto const flags = sleRippleState->getFlags();
311  sleRippleState->setFieldU32(sfFlags, flags | lsfAMMNode);
312  sb.update(sleRippleState);
313  }
314  }
315  return tesSUCCESS;
316  };
317 
318  // Send asset1.
319  res = sendAndTrustSet(amount);
320  if (res != tesSUCCESS)
321  {
322  JLOG(j_.debug()) << "AMM Instance: failed to send " << amount;
323  return {res, false};
324  }
325 
326  // Send asset2.
327  res = sendAndTrustSet(amount2);
328  if (res != tesSUCCESS)
329  {
330  JLOG(j_.debug()) << "AMM Instance: failed to send " << amount2;
331  return {res, false};
332  }
333 
334  JLOG(j_.debug()) << "AMM Instance: success " << *ammAccount << " "
335  << ammKeylet.key << " " << lpTokens << " " << amount << " "
336  << amount2;
337  auto addOrderBook =
338  [&](Issue const& issueIn, Issue const& issueOut, std::uint64_t uRate) {
339  Book const book{issueIn, issueOut};
340  auto const dir = keylet::quality(keylet::book(book), uRate);
341  if (auto const bookExisted = static_cast<bool>(sb.read(dir));
342  !bookExisted)
343  ctx_.app.getOrderBookDB().addOrderBook(book);
344  };
345  addOrderBook(amount.issue(), amount2.issue(), getRate(amount2, amount));
346  addOrderBook(amount2.issue(), amount.issue(), getRate(amount, amount2));
347 
348  return {res, res == tesSUCCESS};
349 }
350 
351 TER
353 {
354  // This is the ledger view that we work against. Transactions are applied
355  // as we go on processing transactions.
356  Sandbox sb(&ctx_.view());
357 
358  auto const result = applyCreate(ctx_, sb, account_, j_);
359  if (result.second)
360  sb.apply(ctx_.rawView());
361 
362  return result.first;
363 }
364 
365 } // namespace ripple
ripple::initializeFeeAuctionVote
void initializeFeeAuctionVote(ApplyView &view, std::shared_ptr< SLE > &ammSle, AccountID const &account, Issue const &lptIssue, std::uint16_t tfee)
Initialize Auction and Voting slots and set the trading/discounted fee.
Definition: AMMUtils.cpp:272
ripple::tecFROZEN
@ tecFROZEN
Definition: TER.h:274
ripple::Application::getOrderBookDB
virtual OrderBookDB & getOrderBookDB()=0
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:130
ripple::tecUNFUNDED_AMM
@ tecUNFUNDED_AMM
Definition: TER.h:299
ripple::Issue
A currency issued by an account.
Definition: Issue.h:35
ripple::tecINSUF_RESERVE_LINE
@ tecINSUF_RESERVE_LINE
Definition: TER.h:259
ripple::sfAsset
const SF_ISSUE sfAsset
ripple::Rules::enabled
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition: Rules.cpp:94
std::shared_ptr< STLedgerEntry >
ripple::PreclaimContext::view
ReadView const & view
Definition: Transactor.h:56
ripple::AMMCreate::calculateBaseFee
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: AMMCreate.cpp:82
ripple::accountSend
TER accountSend(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, beast::Journal j, WaiveTransferFee waiveFee)
Definition: View.cpp:1142
ripple::PreclaimContext::j
const beast::Journal j
Definition: Transactor.h:60
ripple::applyCreate
static std::pair< TER, bool > applyCreate(ApplyContext &ctx_, Sandbox &sb, AccountID const &account_, beast::Journal j_)
Definition: AMMCreate.cpp:205
ripple::lsfDisableMaster
@ lsfDisableMaster
Definition: LedgerFormats.h:235
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:347
ripple::sfAmount2
const SF_AMOUNT sfAmount2
ripple::sfAmount
const SF_AMOUNT sfAmount
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:89
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:609
ripple::WaiveTransferFee::Yes
@ Yes
ripple::ammLPTIssue
Issue ammLPTIssue(Currency const &cur1, Currency const &cur2, AccountID const &ammAccountID)
Calculate LPT Issue from AMM asset pair.
Definition: AMMCore.cpp:56
ripple::Sandbox::apply
void apply(RawView &to)
Definition: Sandbox.h:55
ripple::AMMCreate::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: AMMCreate.cpp:36
std::pair
ripple::sfSequence
const SF_UINT32 sfSequence
ripple::sfLPTokenBalance
const SF_AMOUNT sfLPTokenBalance
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::accountHolds
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
Definition: View.cpp:226
ripple::ammEnabled
bool ammEnabled(Rules const &)
Return true if required AMM amendments are enabled.
Definition: AMMCore.cpp:126
ripple::LedgerHeader::parentHash
uint256 parentHash
Definition: LedgerHeader.h:52
ripple::keylet::amm
Keylet amm(Issue const &issue1, Issue const &issue2) noexcept
AMM entry.
Definition: Indexes.cpp:375
ripple::Unexpected
Unexpected(E(&)[N]) -> Unexpected< E const * >
ripple::detail::ApplyViewBase::update
void update(std::shared_ptr< SLE > const &sle) override
Indicate changes to a peeked SLE.
Definition: ApplyViewBase.cpp:146
ripple::ApplyContext::journal
const beast::Journal journal
Definition: ApplyContext.h:51
ripple::ApplyContext::rawView
RawView & rawView()
Definition: ApplyContext.h:67
ripple::terNO_RIPPLE
@ terNO_RIPPLE
Definition: TER.h:207
ripple::lsfAllowTrustLineClawback
@ lsfAllowTrustLineClawback
Definition: LedgerFormats.h:253
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:38
ripple::ammAccountID
AccountID ammAccountID(std::uint16_t prefix, uint256 const &parentHash, uint256 const &ammID)
Calculate AMM account ID.
Definition: AMMCore.cpp:30
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:78
ripple::lsfDepositAuth
@ lsfDepositAuth
Definition: LedgerFormats.h:240
ripple::sfTradingFee
const SF_UINT16 sfTradingFee
ripple::requireAuth
TER requireAuth(ReadView const &view, Issue const &issue, AccountID const &account)
Check if the account requires authorization.
Definition: View.cpp:1511
ripple::invalidAMMAmount
NotTEC invalidAMMAmount(STAmount const &amount, std::optional< std::pair< Issue, Issue >> const &pair=std::nullopt, bool validZero=false)
Validate the amount.
Definition: AMMCore.cpp:94
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:47
ripple::featureDeletableAccounts
const uint256 featureDeletableAccounts
ripple::Fees::increment
XRPAmount increment
Definition: protocol/Fees.h:36
ripple::getRate
std::uint64_t getRate(STAmount const &offerOut, STAmount const &offerIn)
Definition: STAmount.cpp:495
ripple::AMMCreate::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition: AMMCreate.cpp:89
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:82
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:109
ripple::temBAD_AMM_TOKENS
@ temBAD_AMM_TOKENS
Definition: TER.h:127
ripple::lsfDefaultRipple
@ lsfDefaultRipple
Definition: LedgerFormats.h:238
ripple::lsfAMMNode
@ lsfAMMNode
Definition: LedgerFormats.h:269
ripple::sfAsset2
const SF_ISSUE sfAsset2
ripple::Expected
Definition: Expected.h:132
ripple::detail::ApplyViewBase::info
LedgerInfo const & info() const override
Returns information about the ledger.
Definition: ApplyViewBase.cpp:40
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:134
std::minmax
T minmax(T... args)
ripple::tecDUPLICATE
@ tecDUPLICATE
Definition: TER.h:286
ripple::tecAMM_INVALID_TOKENS
@ tecAMM_INVALID_TOKENS
Definition: TER.h:302
ripple::TERSubset< CanCvtToTER >
ripple::Sandbox
Discardable, editable view to a ledger.
Definition: Sandbox.h:34
ripple::AMMCreate::doApply
TER doApply() override
Attempt to create the AMM instance.
Definition: AMMCreate.cpp:352
ripple::TER
TERSubset< CanCvtToTER > TER
Definition: TER.h:580
ripple::STAmount
Definition: STAmount.h:45
beast::Journal::error
Stream error() const
Definition: Journal.h:333
ripple::tecINTERNAL
@ tecINTERNAL
Definition: TER.h:281
ripple::xrpLiquid
XRPAmount xrpLiquid(ReadView const &view, AccountID const &id, std::int32_t ownerCountAdj, beast::Journal j)
Definition: View.cpp:346
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:481
ripple::STTx
Definition: STTx.h:45
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:89
ripple::ApplyContext
State information when applying a tx.
Definition: ApplyContext.h:35
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint16_t
ripple::keylet::book
static const book_t book
Definition: Indexes.h:101
ripple::keylet::line
Keylet line(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition: Indexes.cpp:194
ripple::temBAD_FEE
@ temBAD_FEE
Definition: TER.h:90
ripple::sfAMMID
const SF_UINT256 sfAMMID
ripple::ReadView::read
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
ripple::ApplyContext::view
ApplyView & view()
Definition: ApplyContext.h:54
ripple::STIssue
Definition: STIssue.h:31
ripple::PreclaimContext::tx
STTx const & tx
Definition: Transactor.h:58
ripple::PreclaimContext
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:52
ripple::detail::ApplyViewBase::insert
void insert(std::shared_ptr< SLE > const &sle) override
Insert a new state SLE.
Definition: ApplyViewBase.cpp:140
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:54
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::TRADING_FEE_THRESHOLD
constexpr std::uint16_t TRADING_FEE_THRESHOLD
Definition: AMMCore.h:31
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:107
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:112
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:122
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::ammLPTokens
STAmount ammLPTokens(STAmount const &asset1, STAmount const &asset2, Issue const &lptIssue)
Definition: AMMHelpers.cpp:25
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:276
ripple::sfBalance
const SF_AMOUNT sfBalance
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:88
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::detail::ApplyViewBase::read
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
Definition: ApplyViewBase.cpp:71
ripple::Book
Specifies an order book.
Definition: Book.h:33
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::detail::ApplyViewBase::peek
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
Definition: ApplyViewBase.cpp:128
ripple::keylet::quality
Keylet quality(Keylet const &k, std::uint64_t q) noexcept
The initial directory page for a specific quality.
Definition: Indexes.cpp:229
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:35
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:31
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:36
ripple::tfUniversalMask
constexpr std::uint32_t tfUniversalMask
Definition: TxFlags.h:60
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:226
ripple::Transactor::account_
const AccountID account_
Definition: Transactor.h:91
ripple::isFrozen
bool isFrozen(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer)
Definition: View.cpp:203
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::Issue::account
AccountID account
Definition: Issue.h:39
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:540
ripple::OrderBookDB::addOrderBook
void addOrderBook(Book const &)
Definition: OrderBookDB.cpp:168