rippled
Transactor.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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/main/Application.h>
21 #include <ripple/app/misc/LoadFeeTrack.h>
22 #include <ripple/app/tx/apply.h>
23 #include <ripple/app/tx/impl/SignerEntries.h>
24 #include <ripple/app/tx/impl/Transactor.h>
25 #include <ripple/basics/Log.h>
26 #include <ripple/basics/contract.h>
27 #include <ripple/core/Config.h>
28 #include <ripple/json/to_string.h>
29 #include <ripple/ledger/View.h>
30 #include <ripple/protocol/Feature.h>
31 #include <ripple/protocol/Indexes.h>
32 #include <ripple/protocol/Protocol.h>
33 #include <ripple/protocol/STAccount.h>
34 #include <ripple/protocol/UintTypes.h>
35 
36 namespace ripple {
37 
39 NotTEC
41 {
42  auto const txID = ctx.tx.getTransactionID();
43 
44  if (txID == beast::zero)
45  {
46  JLOG(ctx.j.warn())
47  << "applyTransaction: transaction id may not be zero";
48  return temINVALID;
49  }
50 
51  return tesSUCCESS;
52 }
53 
55 NotTEC
57 {
58  auto const ret = preflight0(ctx);
59  if (!isTesSuccess(ret))
60  return ret;
61 
62  auto const id = ctx.tx.getAccountID(sfAccount);
63  if (id == beast::zero)
64  {
65  JLOG(ctx.j.warn()) << "preflight1: bad account id";
66  return temBAD_SRC_ACCOUNT;
67  }
68 
69  // No point in going any further if the transaction fee is malformed.
70  auto const fee = ctx.tx.getFieldAmount(sfFee);
71  if (!fee.native() || fee.negative() || !isLegalAmount(fee.xrp()))
72  {
73  JLOG(ctx.j.debug()) << "preflight1: invalid fee";
74  return temBAD_FEE;
75  }
76 
77  auto const spk = ctx.tx.getSigningPubKey();
78 
79  if (!spk.empty() && !publicKeyType(makeSlice(spk)))
80  {
81  JLOG(ctx.j.debug()) << "preflight1: invalid signing key";
82  return temBAD_SIGNATURE;
83  }
84 
85  return tesSUCCESS;
86 }
87 
89 NotTEC
91 {
92  auto const sigValid = checkValidity(
93  ctx.app.getHashRouter(), ctx.tx, ctx.rules, ctx.app.config());
94  if (sigValid.first == Validity::SigBad)
95  {
96  JLOG(ctx.j.debug()) << "preflight2: bad signature. " << sigValid.second;
97  return temINVALID;
98  }
99  return tesSUCCESS;
100 }
101 
102 //------------------------------------------------------------------------------
103 
105  Application& app_,
106  STTx const& tx_,
107  Rules const& rules_,
108  ApplyFlags flags_,
109  beast::Journal j_)
110  : app(app_), tx(tx_), rules(rules_), flags(flags_), j(j_)
111 {
112 }
113 
114 //------------------------------------------------------------------------------
115 
116 Transactor::Transactor(ApplyContext& ctx) : ctx_(ctx), j_(ctx.journal)
117 {
118 }
119 
120 FeeUnit64
122 {
123  // Returns the fee in fee units.
124 
125  // The computation has two parts:
126  // * The base fee, which is the same for most transactions.
127  // * The additional cost of each multisignature on the transaction.
128  FeeUnit64 const baseFee = safe_cast<FeeUnit64>(view.fees().units);
129 
130  // Each signer adds one more baseFee to the minimum required fee
131  // for the transaction.
132  std::size_t const signerCount =
134 
135  return baseFee + (signerCount * baseFee);
136 }
137 
138 XRPAmount
140 {
141  return tx[sfFee].xrp();
142 }
143 
144 XRPAmount
146  Application& app,
147  FeeUnit64 baseFee,
148  Fees const& fees,
149  ApplyFlags flags)
150 {
151  return scaleFeeLoad(baseFee, app.getFeeTrack(), fees, flags & tapUNLIMITED);
152 }
153 
154 XRPAmount
156 {
157  return beast::zero;
158 }
159 
160 TER
162 {
163  auto const feePaid = calculateFeePaid(ctx.tx);
164  if (!isLegalAmount(feePaid) || feePaid < beast::zero)
165  return temBAD_FEE;
166 
167  auto const feeDue =
168  minimumFee(ctx.app, baseFee, ctx.view.fees(), ctx.flags);
169 
170  // Only check fee is sufficient when the ledger is open.
171  if (ctx.view.open() && feePaid < feeDue)
172  {
173  JLOG(ctx.j.trace()) << "Insufficient fee paid: " << to_string(feePaid)
174  << "/" << to_string(feeDue);
175  return telINSUF_FEE_P;
176  }
177 
178  if (feePaid == beast::zero)
179  return tesSUCCESS;
180 
181  auto const id = ctx.tx.getAccountID(sfAccount);
182  auto const sle = ctx.view.read(keylet::account(id));
183  if (!sle)
184  return terNO_ACCOUNT;
185 
186  auto const balance = (*sle)[sfBalance].xrp();
187 
188  if (balance < feePaid)
189  {
190  JLOG(ctx.j.trace()) << "Insufficient balance:"
191  << " balance=" << to_string(balance)
192  << " paid=" << to_string(feePaid);
193 
194  if ((balance > beast::zero) && !ctx.view.open())
195  {
196  // Closed ledger, non-zero balance, less than fee
197  return tecINSUFF_FEE;
198  }
199 
200  return terINSUF_FEE_B;
201  }
202 
203  return tesSUCCESS;
204 }
205 
206 TER
208 {
209  auto const feePaid = calculateFeePaid(ctx_.tx);
210 
211  auto const sle = view().peek(keylet::account(account_));
212  if (!sle)
213  return tefINTERNAL;
214 
215  // Deduct the fee, so it's not available during the transaction.
216  // Will only write the account back if the transaction succeeds.
217 
218  mSourceBalance -= feePaid;
219  sle->setFieldAmount(sfBalance, mSourceBalance);
220 
221  // VFALCO Should we call view().rawDestroyXRP() here as well?
222 
223  return tesSUCCESS;
224 }
225 
226 NotTEC
228 {
229  auto const id = ctx.tx.getAccountID(sfAccount);
230 
231  auto const sle = ctx.view.read(keylet::account(id));
232 
233  if (!sle)
234  {
235  JLOG(ctx.j.trace())
236  << "applyTransaction: delay: source account does not exist "
238  return terNO_ACCOUNT;
239  }
240 
241  std::uint32_t const t_seq = ctx.tx.getSequence();
242  std::uint32_t const a_seq = sle->getFieldU32(sfSequence);
243 
244  if (t_seq != a_seq)
245  {
246  if (a_seq < t_seq)
247  {
248  JLOG(ctx.j.trace())
249  << "applyTransaction: has future sequence number "
250  << "a_seq=" << a_seq << " t_seq=" << t_seq;
251  return terPRE_SEQ;
252  }
253 
254  if (ctx.view.txExists(ctx.tx.getTransactionID()))
255  return tefALREADY;
256 
257  JLOG(ctx.j.trace()) << "applyTransaction: has past sequence number "
258  << "a_seq=" << a_seq << " t_seq=" << t_seq;
259  return tefPAST_SEQ;
260  }
261 
262  if (ctx.tx.isFieldPresent(sfAccountTxnID) &&
263  (sle->getFieldH256(sfAccountTxnID) !=
265  return tefWRONG_PRIOR;
266 
268  (ctx.view.seq() > ctx.tx.getFieldU32(sfLastLedgerSequence)))
269  return tefMAX_LEDGER;
270 
271  return tesSUCCESS;
272 }
273 
274 void
276 {
277  auto const sle = view().peek(keylet::account(account_));
278  if (!sle)
279  return;
280 
281  std::uint32_t const t_seq = ctx_.tx.getSequence();
282 
283  sle->setFieldU32(sfSequence, t_seq + 1);
284 
285  if (sle->isFieldPresent(sfAccountTxnID))
286  sle->setFieldH256(sfAccountTxnID, ctx_.tx.getTransactionID());
287 }
288 
289 // check stuff before you bother to lock the ledger
290 void
292 {
294  assert(account_ != beast::zero);
295 }
296 
297 TER
299 {
300  preCompute();
301 
302  // If the transactor requires a valid account and the transaction doesn't
303  // list one, preflight will have already a flagged a failure.
304  auto const sle = view().peek(keylet::account(account_));
305 
306  // sle must exist except for transactions
307  // that allow zero account.
308  assert(sle != nullptr || account_ == beast::zero);
309 
310  if (sle)
311  {
312  mPriorBalance = STAmount((*sle)[sfBalance]).xrp();
314 
315  setSeq();
316 
317  auto result = payFee();
318 
319  if (result != tesSUCCESS)
320  return result;
321 
322  view().update(sle);
323  }
324 
325  return doApply();
326 }
327 
328 NotTEC
330 {
331  // If the pk is empty, then we must be multi-signing.
332  if (ctx.tx.getSigningPubKey().empty())
333  return checkMultiSign(ctx);
334 
335  return checkSingleSign(ctx);
336 }
337 
338 NotTEC
340 {
341  // Check that the value in the signing key slot is a public key.
342  auto const pkSigner = ctx.tx.getSigningPubKey();
343  if (!publicKeyType(makeSlice(pkSigner)))
344  {
345  JLOG(ctx.j.trace())
346  << "checkSingleSign: signing public key type is unknown";
347  return tefBAD_AUTH; // FIXME: should be better error!
348  }
349 
350  // Look up the account.
351  auto const idSigner = calcAccountID(PublicKey(makeSlice(pkSigner)));
352  auto const idAccount = ctx.tx.getAccountID(sfAccount);
353  auto const sleAccount = ctx.view.read(keylet::account(idAccount));
354  if (!sleAccount)
355  return terNO_ACCOUNT;
356 
357  bool const isMasterDisabled = sleAccount->isFlag(lsfDisableMaster);
358 
360  {
361  // Signed with regular key.
362  if ((*sleAccount)[~sfRegularKey] == idSigner)
363  {
364  return tesSUCCESS;
365  }
366 
367  // Signed with enabled mater key.
368  if (!isMasterDisabled && idAccount == idSigner)
369  {
370  return tesSUCCESS;
371  }
372 
373  // Signed with disabled master key.
374  if (isMasterDisabled && idAccount == idSigner)
375  {
376  return tefMASTER_DISABLED;
377  }
378 
379  // Signed with any other key.
380  return tefBAD_AUTH;
381  }
382 
383  if (idSigner == idAccount)
384  {
385  // Signing with the master key. Continue if it is not disabled.
386  if (isMasterDisabled)
387  return tefMASTER_DISABLED;
388  }
389  else if ((*sleAccount)[~sfRegularKey] == idSigner)
390  {
391  // Signing with the regular key. Continue.
392  }
393  else if (sleAccount->isFieldPresent(sfRegularKey))
394  {
395  // Signing key does not match master or regular key.
396  JLOG(ctx.j.trace())
397  << "checkSingleSign: Not authorized to use account.";
398  return tefBAD_AUTH;
399  }
400  else
401  {
402  // No regular key on account and signing key does not match master key.
403  // FIXME: Why differentiate this case from tefBAD_AUTH?
404  JLOG(ctx.j.trace())
405  << "checkSingleSign: Not authorized to use account.";
406  return tefBAD_AUTH_MASTER;
407  }
408 
409  return tesSUCCESS;
410 }
411 
412 NotTEC
414 {
415  auto const id = ctx.tx.getAccountID(sfAccount);
416  // Get mTxnAccountID's SignerList and Quorum.
417  std::shared_ptr<STLedgerEntry const> sleAccountSigners =
418  ctx.view.read(keylet::signers(id));
419  // If the signer list doesn't exist the account is not multi-signing.
420  if (!sleAccountSigners)
421  {
422  JLOG(ctx.j.trace())
423  << "applyTransaction: Invalid: Not a multi-signing account.";
424  return tefNOT_MULTI_SIGNING;
425  }
426 
427  // We have plans to support multiple SignerLists in the future. The
428  // presence and defaulted value of the SignerListID field will enable that.
429  assert(sleAccountSigners->isFieldPresent(sfSignerListID));
430  assert(sleAccountSigners->getFieldU32(sfSignerListID) == 0);
431 
432  auto accountSigners =
433  SignerEntries::deserialize(*sleAccountSigners, ctx.j, "ledger");
434  if (accountSigners.second != tesSUCCESS)
435  return accountSigners.second;
436 
437  // Get the array of transaction signers.
438  STArray const& txSigners(ctx.tx.getFieldArray(sfSigners));
439 
440  // Walk the accountSigners performing a variety of checks and see if
441  // the quorum is met.
442 
443  // Both the multiSigners and accountSigners are sorted by account. So
444  // matching multi-signers to account signers should be a simple
445  // linear walk. *All* signers must be valid or the transaction fails.
446  std::uint32_t weightSum = 0;
447  auto iter = accountSigners.first.begin();
448  for (auto const& txSigner : txSigners)
449  {
450  AccountID const txSignerAcctID = txSigner.getAccountID(sfAccount);
451 
452  // Attempt to match the SignerEntry with a Signer;
453  while (iter->account < txSignerAcctID)
454  {
455  if (++iter == accountSigners.first.end())
456  {
457  JLOG(ctx.j.trace())
458  << "applyTransaction: Invalid SigningAccount.Account.";
459  return tefBAD_SIGNATURE;
460  }
461  }
462  if (iter->account != txSignerAcctID)
463  {
464  // The SigningAccount is not in the SignerEntries.
465  JLOG(ctx.j.trace())
466  << "applyTransaction: Invalid SigningAccount.Account.";
467  return tefBAD_SIGNATURE;
468  }
469 
470  // We found the SigningAccount in the list of valid signers. Now we
471  // need to compute the accountID that is associated with the signer's
472  // public key.
473  auto const spk = txSigner.getFieldVL(sfSigningPubKey);
474 
475  if (!publicKeyType(makeSlice(spk)))
476  {
477  JLOG(ctx.j.trace())
478  << "checkMultiSign: signing public key type is unknown";
479  return tefBAD_SIGNATURE;
480  }
481 
482  AccountID const signingAcctIDFromPubKey =
484 
485  // Verify that the signingAcctID and the signingAcctIDFromPubKey
486  // belong together. Here is are the rules:
487  //
488  // 1. "Phantom account": an account that is not in the ledger
489  // A. If signingAcctID == signingAcctIDFromPubKey and the
490  // signingAcctID is not in the ledger then we have a phantom
491  // account.
492  // B. Phantom accounts are always allowed as multi-signers.
493  //
494  // 2. "Master Key"
495  // A. signingAcctID == signingAcctIDFromPubKey, and signingAcctID
496  // is in the ledger.
497  // B. If the signingAcctID in the ledger does not have the
498  // asfDisableMaster flag set, then the signature is allowed.
499  //
500  // 3. "Regular Key"
501  // A. signingAcctID != signingAcctIDFromPubKey, and signingAcctID
502  // is in the ledger.
503  // B. If signingAcctIDFromPubKey == signingAcctID.RegularKey (from
504  // ledger) then the signature is allowed.
505  //
506  // No other signatures are allowed. (January 2015)
507 
508  // In any of these cases we need to know whether the account is in
509  // the ledger. Determine that now.
510  auto sleTxSignerRoot = ctx.view.read(keylet::account(txSignerAcctID));
511 
512  if (signingAcctIDFromPubKey == txSignerAcctID)
513  {
514  // Either Phantom or Master. Phantoms automatically pass.
515  if (sleTxSignerRoot)
516  {
517  // Master Key. Account may not have asfDisableMaster set.
518  std::uint32_t const signerAccountFlags =
519  sleTxSignerRoot->getFieldU32(sfFlags);
520 
521  if (signerAccountFlags & lsfDisableMaster)
522  {
523  JLOG(ctx.j.trace())
524  << "applyTransaction: Signer:Account lsfDisableMaster.";
525  return tefMASTER_DISABLED;
526  }
527  }
528  }
529  else
530  {
531  // May be a Regular Key. Let's find out.
532  // Public key must hash to the account's regular key.
533  if (!sleTxSignerRoot)
534  {
535  JLOG(ctx.j.trace()) << "applyTransaction: Non-phantom signer "
536  "lacks account root.";
537  return tefBAD_SIGNATURE;
538  }
539 
540  if (!sleTxSignerRoot->isFieldPresent(sfRegularKey))
541  {
542  JLOG(ctx.j.trace())
543  << "applyTransaction: Account lacks RegularKey.";
544  return tefBAD_SIGNATURE;
545  }
546  if (signingAcctIDFromPubKey !=
547  sleTxSignerRoot->getAccountID(sfRegularKey))
548  {
549  JLOG(ctx.j.trace())
550  << "applyTransaction: Account doesn't match RegularKey.";
551  return tefBAD_SIGNATURE;
552  }
553  }
554  // The signer is legitimate. Add their weight toward the quorum.
555  weightSum += iter->weight;
556  }
557 
558  // Cannot perform transaction if quorum is not met.
559  if (weightSum < sleAccountSigners->getFieldU32(sfSignerQuorum))
560  {
561  JLOG(ctx.j.trace())
562  << "applyTransaction: Signers failed to meet quorum.";
563  return tefBAD_QUORUM;
564  }
565 
566  // Met the quorum. Continue.
567  return tesSUCCESS;
568 }
569 
570 //------------------------------------------------------------------------------
571 
572 static void
574  ApplyView& view,
575  std::vector<uint256> const& offers,
576  beast::Journal viewJ)
577 {
578  int removed = 0;
579 
580  for (auto const& index : offers)
581  {
582  if (auto const sleOffer = view.peek(keylet::offer(index)))
583  {
584  // offer is unfunded
585  offerDelete(view, sleOffer, viewJ);
586  if (++removed == unfundedOfferRemoveLimit)
587  return;
588  }
589  }
590 }
591 
593 XRPAmount
595 {
596  ctx_.discard();
597 
598  auto const txnAcct =
600  if (!txnAcct)
601  // The account should never be missing from the ledger. But if it
602  // is missing then we can't very well charge it a fee, can we?
603  return beast::zero;
604 
605  auto const balance = txnAcct->getFieldAmount(sfBalance).xrp();
606 
607  // balance should have already been checked in checkFee / preFlight.
608  assert(balance != beast::zero && (!view().open() || balance >= fee));
609 
610  // We retry/reject the transaction if the account balance is zero or we're
611  // applying against an open ledger and the balance is less than the fee
612  if (fee > balance)
613  fee = balance;
614 
615  // Since we reset the context, we need to charge the fee and update
616  // the account's sequence number again.
617  txnAcct->setFieldAmount(sfBalance, balance - fee);
618  txnAcct->setFieldU32(sfSequence, ctx_.tx.getSequence() + 1);
619 
620  view().update(txnAcct);
621 
622  return fee;
623 }
624 
625 //------------------------------------------------------------------------------
628 {
629  JLOG(j_.trace()) << "apply: " << ctx_.tx.getTransactionID();
630 
631 #ifdef DEBUG
632  {
633  Serializer ser;
634  ctx_.tx.add(ser);
635  SerialIter sit(ser.slice());
636  STTx s2(sit);
637 
638  if (!s2.isEquivalent(ctx_.tx))
639  {
640  JLOG(j_.fatal()) << "Transaction serdes mismatch";
642  JLOG(j_.fatal()) << s2.getJson(JsonOptions::none);
643  assert(false);
644  }
645  }
646 #endif
647 
648  auto result = ctx_.preclaimResult;
649  if (result == tesSUCCESS)
650  result = apply();
651 
652  // No transaction can return temUNKNOWN from apply,
653  // and it can't be passed in from a preclaim.
654  assert(result != temUNKNOWN);
655 
656  if (auto stream = j_.trace())
657  stream << "preclaim result: " << transToken(result);
658 
659  bool applied = isTesSuccess(result);
660  auto fee = ctx_.tx.getFieldAmount(sfFee).xrp();
661 
662  if (ctx_.size() > oversizeMetaDataCap)
663  result = tecOVERSIZE;
664 
665  if (isTecClaim(result) && (view().flags() & tapFAIL_HARD))
666  {
667  // If the tapFAIL_HARD flag is set, a tec result
668  // must not do anything
669 
670  ctx_.discard();
671  applied = false;
672  }
673  else if (
674  (result == tecOVERSIZE) || (result == tecKILLED) ||
675  (isTecClaimHardFail(result, view().flags())))
676  {
677  JLOG(j_.trace()) << "reapplying because of " << transToken(result);
678 
679  std::vector<uint256> removedOffers;
680 
681  if ((result == tecOVERSIZE) || (result == tecKILLED))
682  {
683  ctx_.visit([&removedOffers](
684  uint256 const& index,
685  bool isDelete,
686  std::shared_ptr<SLE const> const& before,
688  if (isDelete)
689  {
690  assert(before && after);
691  if (before && after && (before->getType() == ltOFFER) &&
692  (before->getFieldAmount(sfTakerPays) ==
693  after->getFieldAmount(sfTakerPays)))
694  {
695  // Removal of offer found or made unfunded
696  removedOffers.push_back(index);
697  }
698  }
699  });
700  }
701 
702  // Reset the context, potentially adjusting the fee
703  fee = reset(fee);
704 
705  // If necessary, remove any offers found unfunded during processing
706  if ((result == tecOVERSIZE) || (result == tecKILLED))
708  view(), removedOffers, ctx_.app.journal("View"));
709 
710  applied = true;
711  }
712 
713  if (applied)
714  {
715  // Check invariants: if `tecINVARIANT_FAILED` is not returned, we can
716  // proceed to apply the tx
717  result = ctx_.checkInvariants(result, fee);
718 
719  if (result == tecINVARIANT_FAILED)
720  {
721  // if invariants checking failed again, reset the context and
722  // attempt to only claim a fee.
723  fee = reset(fee);
724 
725  // Check invariants again to ensure the fee claiming doesn't
726  // violate invariants.
727  result = ctx_.checkInvariants(result, fee);
728  }
729 
730  // We ran through the invariant checker, which can, in some cases,
731  // return a tef error code. Don't apply the transaction in that case.
732  if (!isTecClaim(result) && !isTesSuccess(result))
733  applied = false;
734  }
735 
736  if (applied)
737  {
738  // Transaction succeeded fully or (retries are not allowed and the
739  // transaction could claim a fee)
740 
741  // The transactor and invariant checkers guarantee that this will
742  // *never* trigger but if it, somehow, happens, don't allow a tx
743  // that charges a negative fee.
744  if (fee < beast::zero)
745  Throw<std::logic_error>("fee charged is negative!");
746 
747  // Charge whatever fee they specified. The fee has already been
748  // deducted from the balance of the account that issued the
749  // transaction. We just need to account for it in the ledger
750  // header.
751  if (!view().open() && fee != beast::zero)
752  ctx_.destroyXRP(fee);
753 
754  // Once we call apply, we will no longer be able to look at view()
755  ctx_.apply(result);
756  }
757 
758  JLOG(j_.trace()) << (applied ? "applied" : "not applied")
759  << transToken(result);
760 
761  return {result, applied};
762 }
763 
764 } // namespace ripple
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:339
ripple::Transactor::calculateMaxSpend
static XRPAmount calculateMaxSpend(STTx const &tx)
Definition: Transactor.cpp:155
ripple::Application
Definition: Application.h:97
ripple::STObject::getFieldArray
const STArray & getFieldArray(SField const &field) const
Definition: STObject.cpp:597
ripple::sfRegularKey
const SF_Account sfRegularKey(access, STI_ACCOUNT, 8, "RegularKey")
Definition: SField.h:487
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:90
ripple::makeSlice
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)
Definition: Slice.h:240
ripple::Transactor::checkMultiSign
static NotTEC checkMultiSign(PreclaimContext const &ctx)
Definition: Transactor.cpp:413
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:149
ripple::tecINVARIANT_FAILED
@ tecINVARIANT_FAILED
Definition: TER.h:271
std::shared_ptr
STL class.
ripple::ApplyContext::checkInvariants
TER checkInvariants(TER const result, XRPAmount const fee)
Applies all invariant checkers one by one.
Definition: ApplyContext.cpp:147
ripple::PreclaimContext::view
ReadView const & view
Definition: Transactor.h:57
ripple::isLegalAmount
bool isLegalAmount(XRPAmount const &amount)
Returns true if the amount does not exceed the initial XRP in existence.
Definition: SystemParameters.h:47
ripple::PreclaimContext::app
Application & app
Definition: Transactor.h:56
ripple::terINSUF_FEE_B
@ terINSUF_FEE_B
Definition: TER.h:189
ripple::PreclaimContext::j
const beast::Journal j
Definition: Transactor.h:61
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::publicKeyType
boost::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:203
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
ripple::lsfDisableMaster
@ lsfDisableMaster
Definition: LedgerFormats.h:109
ripple::sfSigners
const SField sfSigners(access, STI_ARRAY, 3, "Signers", SField::sMD_Default, SField::notSigning)
Definition: SField.h:516
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:90
ripple::Transactor::checkSingleSign
static NotTEC checkSingleSign(PreclaimContext const &ctx)
Definition: Transactor.cpp:339
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:576
ripple::ApplyContext::preclaimResult
const TER preclaimResult
Definition: ApplyContext.h:49
std::pair
ripple::Transactor::operator()
std::pair< TER, bool > operator()()
Process the transaction.
Definition: Transactor.cpp:627
ripple::sfSigningPubKey
const SF_Blob sfSigningPubKey(access, STI_VL, 3, "SigningPubKey")
Definition: SField.h:459
ripple::sfSignerQuorum
const SF_U32 sfSignerQuorum(access, STI_UINT32, 35, "SignerQuorum")
Definition: SField.h:388
std::vector
STL class.
ripple::sfSequence
const SF_U32 sfSequence(access, STI_UINT32, 4, "Sequence")
Definition: SField.h:356
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::Transactor::reset
XRPAmount reset(XRPAmount fee)
Reset the context, discarding any changes made and adjust the fee.
Definition: Transactor.cpp:594
ripple::sfAccount
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
Definition: SField.h:480
ripple::sfFlags
const SF_U32 sfFlags(access, STI_UINT32, 2, "Flags")
Definition: SField.h:354
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:30
ripple::keylet::offer
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
Definition: Indexes.cpp:210
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:29
ripple::sfTakerPays
const SF_Amount sfTakerPays(access, STI_AMOUNT, 4, "TakerPays")
Definition: SField.h:443
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
ripple::transToken
std::string transToken(TER code)
Definition: TER.cpp:193
ripple::scaleFeeLoad
XRPAmount scaleFeeLoad(FeeUnit64 fee, LoadFeeTrack const &feeTrack, Fees const &fees, bool bUnlimited)
Definition: LoadFeeTrack.cpp:89
ripple::ApplyView::update
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
ripple::ReadView::txExists
virtual bool txExists(key_type const &key) const =0
Returns true if a tx exists in the tx map.
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:42
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:39
ripple::Transactor::minimumFee
static XRPAmount minimumFee(Application &app, FeeUnit64 baseFee, Fees const &fees, ApplyFlags flags)
Compute the minimum fee required to process a transaction with a given baseFee based on the current s...
Definition: Transactor.cpp:145
ripple::unfundedOfferRemoveLimit
constexpr std::size_t unfundedOfferRemoveLimit
The maximum number of unfunded offers to delete at once.
Definition: Protocol.h:45
ripple::isTecClaim
bool isTecClaim(TER x)
Definition: TER.h:582
ripple::tefBAD_AUTH
@ tefBAD_AUTH
Definition: TER.h:145
ripple::isTecClaimHardFail
bool isTecClaimHardFail(TER ter, ApplyFlags flags)
Return true if the transaction can claim a fee (tec), and the ApplyFlags do not allow soft failures.
Definition: applySteps.h:35
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:299
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:56
ripple::sfAccountTxnID
const SF_U256 sfAccountTxnID(access, STI_HASH256, 9, "AccountTxnID")
Definition: SField.h:425
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition: ApplyView.h:140
ripple::tecKILLED
@ tecKILLED
Definition: TER.h:274
ripple::Application::getFeeTrack
virtual LoadFeeTrack & getFeeTrack()=0
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:47
ripple::Transactor::doApply
virtual TER doApply()=0
ripple::Transactor::setSeq
void setSeq()
Definition: Transactor.cpp:275
std::vector::push_back
T push_back(T... args)
ripple::STObject::isEquivalent
virtual bool isEquivalent(const STBase &t) const override
Definition: STObject.cpp:277
ripple::tefBAD_QUORUM
@ tefBAD_QUORUM
Definition: TER.h:156
ripple::tecOVERSIZE
@ tecOVERSIZE
Definition: TER.h:269
ripple::base_uint< 160, detail::AccountIDTag >
ripple::sfLastLedgerSequence
const SF_U32 sfLastLedgerSequence(access, STI_UINT32, 27, "LastLedgerSequence")
Definition: SField.h:380
ripple::preflight0
NotTEC preflight0(PreflightContext const &ctx)
Performs early sanity checks on the txid.
Definition: Transactor.cpp:40
ripple::Transactor::checkSign
static NotTEC checkSign(PreclaimContext const &ctx)
Definition: Transactor.cpp:329
ripple::Fees
Reflects the fee settings for a particular ledger.
Definition: ReadView.h:47
ripple::checkValidity
std::pair< Validity, std::string > checkValidity(HashRouter &router, STTx const &tx, Rules const &rules, Config const &config)
Checks transaction signature and local checks.
Definition: apply.cpp:37
ripple::tefMAX_LEDGER
@ tefMAX_LEDGER
Definition: TER.h:154
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:121
ripple::tefMASTER_DISABLED
@ tefMASTER_DISABLED
Definition: TER.h:153
ripple::offerDelete
TER offerDelete(ApplyView &view, std::shared_ptr< SLE > const &sle, beast::Journal j)
Delete an offer.
Definition: View.cpp:896
ripple::Transactor::payFee
TER payFee()
Definition: Transactor.cpp:207
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:562
ripple::ApplyContext::destroyXRP
void destroyXRP(XRPAmount const &fee)
Definition: ApplyContext.h:99
ripple::JsonOptions::none
@ none
ripple::Transactor::apply
TER apply()
Definition: Transactor.cpp:298
ripple::Application::config
virtual Config & config()=0
ripple::sfSignerListID
const SF_U32 sfSignerListID(access, STI_UINT32, 38, "SignerListID")
Definition: SField.h:391
ripple::TERSubset< CanCvtToTER >
ripple::calcAccountID
AccountID calcAccountID(PublicKey const &pk)
Definition: AccountID.cpp:131
ripple::STArray
Definition: STArray.h:28
ripple::temBAD_SRC_ACCOUNT
@ temBAD_SRC_ACCOUNT
Definition: TER.h:101
ripple::telINSUF_FEE_P
@ telINSUF_FEE_P
Definition: TER.h:56
ripple::STAmount
Definition: STAmount.h:42
ripple::PreflightContext::app
Application & app
Definition: Transactor.h:35
ripple::ApplyContext::discard
void discard()
Discard changes and start fresh.
Definition: ApplyContext.cpp:51
ripple::Serializer::slice
Slice slice() const noexcept
Definition: Serializer.h:63
beast::Journal::info
Stream info() const
Definition: Journal.h:321
ripple::fixMasterKeyAsRegularKey
const uint256 fixMasterKeyAsRegularKey
Definition: Feature.cpp:180
ripple::STTx
Definition: STTx.h:42
ripple::Transactor::calculateBaseFee
static FeeUnit64 calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Transactor.cpp:121
ripple::SerialIter
Definition: Serializer.h:308
ripple::tecINSUFF_FEE
@ tecINSUFF_FEE
Definition: TER.h:260
ripple::ApplyContext
State information when applying a tx.
Definition: ApplyContext.h:35
ripple::STTx::getSigningPubKey
Blob getSigningPubKey() const
Definition: STTx.h:111
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint32_t
ripple::temBAD_SIGNATURE
@ temBAD_SIGNATURE
Definition: TER.h:100
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:103
ripple::temUNKNOWN
@ temUNKNOWN
Definition: TER.h:119
ripple::feeunit::TaggedFee
Definition: FeeUnits.h:70
ripple::temBAD_FEE
@ temBAD_FEE
Definition: TER.h:87
ripple::sfFee
const SF_Amount sfFee(access, STI_AMOUNT, 8, "Fee")
Definition: SField.h:447
ripple::ReadView::read
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
ripple::STTx::getJson
Json::Value getJson(JsonOptions options) const override
Definition: STTx.cpp:194
ripple::Transactor::Transactor
Transactor(Transactor const &)=delete
ripple::PreclaimContext::tx
STTx const & tx
Definition: Transactor.h:59
ripple::ApplyContext::apply
void apply(TER)
Apply the transaction result to the base.
Definition: ApplyContext.cpp:57
ripple::ApplyContext::visit
void visit(std::function< void(uint256 const &key, bool isDelete, std::shared_ptr< SLE const > const &before, std::shared_ptr< SLE const > const &after)> const &func)
Visit unapplied changes.
Definition: ApplyContext.cpp:69
ripple::STTx::getSequence
std::uint32_t getSequence() const
Definition: STTx.h:117
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:131
ripple::terNO_ACCOUNT
@ terNO_ACCOUNT
Definition: TER.h:190
ripple::PreflightContext::PreflightContext
PreflightContext(Application &app_, STTx const &tx_, Rules const &rules_, ApplyFlags flags_, beast::Journal j_)
Definition: Transactor.cpp:104
ripple::PreclaimContext
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:53
ripple::Serializer
Definition: Serializer.h:39
ripple::tefNOT_MULTI_SIGNING
@ tefNOT_MULTI_SIGNING
Definition: TER.h:157
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:188
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::STObject::add
virtual void add(Serializer &s) const override
Definition: STObject.h:351
ripple::tapUNLIMITED
@ tapUNLIMITED
Definition: ApplyView.h:47
ripple::sfBalance
const SF_Amount sfBalance(access, STI_AMOUNT, 2, "Balance")
Definition: SField.h:441
ripple::oversizeMetaDataCap
constexpr std::size_t oversizeMetaDataCap
The maximum number of metadata entries allowed in one transaction.
Definition: Protocol.h:48
ripple::tefPAST_SEQ
@ tefPAST_SEQ
Definition: TER.h:151
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:107
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:256
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::tefALREADY
@ tefALREADY
Definition: TER.h:143
ripple::Fees::units
FeeUnit32 units
Definition: ReadView.h:50
ripple::STObject::isFieldPresent
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:401
ripple::Transactor::mPriorBalance
XRPAmount mPriorBalance
Definition: Transactor.h:93
ripple::Transactor::mSourceBalance
XRPAmount mSourceBalance
Definition: Transactor.h:94
ripple::PreclaimContext::flags
ApplyFlags flags
Definition: Transactor.h:60
ripple::tefWRONG_PRIOR
@ tefWRONG_PRIOR
Definition: TER.h:152
ripple::tapFAIL_HARD
@ tapFAIL_HARD
Definition: ApplyView.h:35
std::vector::empty
T empty(T... args)
ripple::Rules
Rules controlling protocol behavior.
Definition: ReadView.h:127
ripple::terPRE_SEQ
@ terPRE_SEQ
Definition: TER.h:194
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:89
ripple::Transactor::account_
AccountID account_
Definition: Transactor.h:92
ripple::Transactor::checkSeq
static NotTEC checkSeq(PreclaimContext const &ctx)
Definition: Transactor.cpp:227
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::after
static bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition: Escrow.cpp:88
std::size_t
ripple::tefBAD_AUTH_MASTER
@ tefBAD_AUTH_MASTER
Definition: TER.h:158
ripple::SignerEntries::deserialize
static std::pair< std::vector< SignerEntry >, NotTEC > deserialize(STObject const &obj, beast::Journal journal, std::string const &annotation)
Definition: SignerEntries.cpp:29
ripple::STArray::size
size_type size() const
Definition: STArray.h:138
ripple::ltOFFER
@ ltOFFER
Definition: LedgerFormats.h:72
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:36
ripple::STObject::getFieldU32
std::uint32_t getFieldU32(SField const &field) const
Definition: STObject.cpp:532
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:32
ripple::Validity::SigBad
@ SigBad
Signature is bad. Didn't do local checks.
ripple::Transactor::calculateFeePaid
static XRPAmount calculateFeePaid(STTx const &tx)
Definition: Transactor.cpp:139
ripple::keylet::signers
static Keylet signers(AccountID const &account, std::uint32_t page) noexcept
Definition: Indexes.cpp:250
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:37
ripple::ApplyContext::size
std::size_t size()
Get the number of unapplied changes.
Definition: ApplyContext.cpp:63
ripple::removeUnfundedOffers
static void removeUnfundedOffers(ApplyView &view, std::vector< uint256 > const &offers, beast::Journal viewJ)
Definition: Transactor.cpp:573
ripple::Transactor::checkFee
static TER checkFee(PreclaimContext const &ctx, FeeUnit64 baseFee)
Definition: Transactor.cpp:161
ripple::ReadView::open
virtual bool open() const =0
Returns true if this reflects an open ledger.
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:213
ripple::Application::getHashRouter
virtual HashRouter & getHashRouter()=0
ripple::Transactor::preCompute
virtual void preCompute()
Definition: Transactor.cpp:291
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:576
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::temINVALID
@ temINVALID
Definition: TER.h:105
ripple::open
void open(soci::session &s, BasicConfig const &config, std::string const &dbName)
Open a soci session.
Definition: SociDB.cpp:100
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::tefBAD_SIGNATURE
@ tefBAD_SIGNATURE
Definition: TER.h:155
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:507
ripple::STObject::getFieldH256
uint256 getFieldH256(SField const &field) const
Definition: STObject.cpp:556