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