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>
44 if (txID == beast::zero)
47 "applyTransaction: transaction id may not be zero";
63 if (
id == beast::zero)
65 JLOG(ctx.
j.
warn()) <<
"preflight1: bad account id";
71 if (!fee.native () || fee.negative () || !
isLegalAmount (fee.xrp ()))
73 JLOG(ctx.
j.
debug()) <<
"preflight1: invalid fee";
81 JLOG(ctx.
j.
debug()) <<
"preflight1: invalid signing key";
97 "preflight2: bad signature. " << sigValid.second;
142 return baseFee + (signerCount * baseFee);
148 return tx[
sfFee].xrp();
177 if (ctx.
view.
open() && feePaid < feeDue)
179 JLOG(ctx.
j.
trace()) <<
"Insufficient fee paid: " <<
184 if (feePaid == beast::zero)
192 auto const balance = (*sle)[
sfBalance].xrp();
194 if (balance < feePaid)
196 JLOG(ctx.
j.
trace()) <<
"Insufficient balance:" <<
200 if ((balance > beast::zero) && !ctx.
view.
open())
242 "applyTransaction: delay: source account does not exist " <<
255 "applyTransaction: has future sequence number " <<
256 "a_seq=" << a_seq <<
" t_seq=" << t_seq;
263 JLOG(ctx.
j.
trace()) <<
"applyTransaction: has past sequence number " <<
264 "a_seq=" << a_seq <<
" t_seq=" << t_seq;
311 assert(sle !=
nullptr ||
account_ == beast::zero);
349 "checkSingleSign: signing public key type is unknown";
372 if (!isMasterDisabled && idAccount == idSigner)
378 if (isMasterDisabled && idAccount == idSigner)
388 if (idSigner == idAccount)
391 if (isMasterDisabled)
402 "checkSingleSign: Not authorized to use account.";
410 "checkSingleSign: Not authorized to use account.";
425 if (!sleAccountSigners)
428 "applyTransaction: Invalid: Not a multi-signing account.";
437 auto accountSigners =
440 return accountSigners.second;
452 auto iter = accountSigners.first.begin ();
453 for (
auto const& txSigner : txSigners)
458 while (iter->account < txSignerAcctID)
460 if (++iter == accountSigners.first.end ())
463 "applyTransaction: Invalid SigningAccount.Account.";
467 if (iter->account != txSignerAcctID)
471 "applyTransaction: Invalid SigningAccount.Account.";
483 "checkMultiSign: signing public key type is unknown";
487 AccountID const signingAcctIDFromPubKey =
515 auto sleTxSignerRoot =
518 if (signingAcctIDFromPubKey == txSignerAcctID)
525 sleTxSignerRoot->getFieldU32 (
sfFlags);
530 "applyTransaction: Signer:Account lsfDisableMaster.";
539 if (!sleTxSignerRoot)
542 "applyTransaction: Non-phantom signer lacks account root.";
549 "applyTransaction: Account lacks RegularKey.";
552 if (signingAcctIDFromPubKey !=
556 "applyTransaction: Account doesn't match RegularKey.";
561 weightSum += iter->weight;
568 "applyTransaction: Signers failed to meet quorum.";
583 for (
auto const& index : offers)
608 auto const balance = txnAcct->getFieldAmount (
sfBalance).xrp ();
611 assert(balance != beast::zero && (!
view().
open() || balance >= fee));
620 txnAcct->setFieldAmount (
sfBalance, balance - fee);
644 "Transaction serdes mismatch";
661 stream <<
"preclaim result: " <<
transToken(result);
695 assert (before &&
after);
696 if (before &&
after &&
697 (before->getType() ==
ltOFFER) &&
748 if (fee < beast::zero)
749 Throw<std::logic_error> (
"fee charged is negative!");
755 if (!
view().
open() && fee != beast::zero)
764 return { result, applied };
static XRPAmount calculateMaxSpend(STTx const &tx)
const STArray & getFieldArray(SField const &field) const
const SF_Account sfRegularKey(access, STI_ACCOUNT, 8, "RegularKey")
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
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)
static NotTEC checkMultiSign(PreclaimContext const &ctx)
static const signers_t signers
TER checkInvariants(TER const result, XRPAmount const fee)
Applies all invariant checkers one by one.
bool isLegalAmount(XRPAmount const &amount)
Returns true if the amount does not exceed the initial XRP in existence.
Stream trace() const
Severity stream access functions.
boost::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
const SField sfSigners(access, STI_ARRAY, 3, "Signers", SField::sMD_Default, SField::notSigning)
static NotTEC checkSingleSign(PreclaimContext const &ctx)
std::pair< TER, bool > operator()()
Process the transaction.
const SF_Blob sfSigningPubKey(access, STI_VL, 3, "SigningPubKey")
const SF_U32 sfSignerQuorum(access, STI_UINT32, 35, "SignerQuorum")
const SF_U32 sfSequence(access, STI_UINT32, 4, "Sequence")
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
XRPAmount reset(XRPAmount fee)
Reset the context, discarding any changes made and adjust the fee.
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
const SF_U32 sfFlags(access, STI_UINT32, 2, "Flags")
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
const SF_Amount sfTakerPays(access, STI_AMOUNT, 4, "TakerPays")
std::string transToken(TER code)
XRPAmount scaleFeeLoad(FeeUnit64 fee, LoadFeeTrack const &feeTrack, Fees const &fees, bool bUnlimited)
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
virtual bool txExists(key_type const &key) const =0
Returns true if a tx exists in the tx map.
std::string to_string(ListDisposition disposition)
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...
constexpr std::size_t unfundedOfferRemoveLimit
The maximum number of unfunded offers to delete at once.
bool isTecClaimHardFail(TER ter, ApplyFlags flags)
Return true if the transaction can claim a fee (tec), and the ApplyFlags do not allow soft failures.
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
const SF_U256 sfAccountTxnID(access, STI_HASH256, 9, "AccountTxnID")
Writeable view to a ledger, for applying a transaction.
virtual LoadFeeTrack & getFeeTrack()=0
virtual bool isEquivalent(const STBase &t) const override
const SF_U32 sfLastLedgerSequence(access, STI_UINT32, 27, "LastLedgerSequence")
NotTEC preflight0(PreflightContext const &ctx)
Performs early sanity checks on the txid.
static NotTEC checkSign(PreclaimContext const &ctx)
Reflects the fee settings for a particular ledger.
std::pair< Validity, std::string > checkValidity(HashRouter &router, STTx const &tx, Rules const &rules, Config const &config)
Checks transaction signature and local checks.
TER offerDelete(ApplyView &view, std::shared_ptr< SLE > const &sle, beast::Journal j)
Delete an offer.
static const account_t account
AccountID getAccountID(SField const &field) const
void destroyXRP(XRPAmount const &fee)
virtual Config & config()=0
const SF_U32 sfSignerListID(access, STI_UINT32, 38, "SignerListID")
AccountID calcAccountID(PublicKey const &pk)
void discard()
Discard changes and start fresh.
Slice slice() const noexcept
const uint256 fixMasterKeyAsRegularKey
static FeeUnit64 calculateBaseFee(ReadView const &view, STTx const &tx)
State information when applying a tx.
Blob getSigningPubKey() const
A generic endpoint for log messages.
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
const SF_Amount sfFee(access, STI_AMOUNT, 8, "Fee")
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
Json::Value getJson(JsonOptions options) const override
Transactor(Transactor const &)=delete
void apply(TER)
Apply the transaction result to the base.
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.
std::uint32_t getSequence() const
uint256 getTransactionID() const
PreflightContext(Application &app_, STTx const &tx_, Rules const &rules_, ApplyFlags flags_, beast::Journal j_)
State information when determining if a tx is likely to claim a fee.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
virtual beast::Journal journal(std::string const &name)=0
virtual void add(Serializer &s) const override
const SF_Amount sfBalance(access, STI_AMOUNT, 2, "Balance")
constexpr std::size_t oversizeMetaDataCap
The maximum number of metadata entries allowed in one transaction.
LedgerIndex seq() const
Returns the sequence number of the base ledger.
virtual Rules const & rules() const =0
Returns the tx processing rules.
bool isFieldPresent(SField const &field) const
Rules controlling protocol behavior.
static NotTEC checkSeq(PreclaimContext const &ctx)
static bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
static std::pair< std::vector< SignerEntry >, NotTEC > deserialize(STObject const &obj, beast::Journal journal, std::string const &annotation)
std::uint32_t getFieldU32(SField const &field) const
State information when preflighting a tx.
@ SigBad
Signature is bad. Didn't do local checks.
static XRPAmount calculateFeePaid(STTx const &tx)
std::size_t size()
Get the number of unapplied changes.
static const offer_t offer
static void removeUnfundedOffers(ApplyView &view, std::vector< uint256 > const &offers, beast::Journal viewJ)
static TER checkFee(PreclaimContext const &ctx, FeeUnit64 baseFee)
virtual bool open() const =0
Returns true if this reflects an open ledger.
virtual HashRouter & getHashRouter()=0
virtual void preCompute()
STAmount const & getFieldAmount(SField const &field) const
void open(soci::session &s, BasicConfig const &config, std::string const &dbName)
Open a soci session.
TERSubset< CanCvtToNotTEC > NotTEC
uint256 getFieldH256(SField const &field) const