1#include <xrpl/tx/invariants/FreezeInvariant.h>
3#include <xrpl/basics/Log.h>
4#include <xrpl/beast/utility/Journal.h>
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/ledger/ReadView.h>
7#include <xrpl/protocol/AccountID.h>
8#include <xrpl/protocol/Feature.h>
9#include <xrpl/protocol/Indexes.h>
10#include <xrpl/protocol/Issue.h>
11#include <xrpl/protocol/LedgerFormats.h>
12#include <xrpl/protocol/SField.h>
13#include <xrpl/protocol/STLedgerEntry.h>
14#include <xrpl/protocol/STTx.h>
15#include <xrpl/protocol/TER.h>
16#include <xrpl/protocol/XRPAmount.h>
17#include <xrpl/tx/invariants/InvariantCheckPrivilege.h>
42 if (balanceChange.signum() == 0)
74 [[maybe_unused]]
bool const enforce = view.
rules().
enabled(featureDeepFreeze);
78 auto const issuerSle =
findIssuer(issue.account, view);
87 "xrpl::TransfersNotFrozen::finalize : enforce "
109 XRPL_ASSERT(
after,
"xrpl::TransfersNotFrozen::isValidEntry : valid after.");
115 if (
after->getType() == ltACCOUNT_ROOT)
127 return after->getType() == ltRIPPLE_STATE && (!before || before->getType() == ltRIPPLE_STATE);
136 auto const getBalance = [](
auto const& line,
auto const& other,
bool zero) {
137 STAmount const amt = line ? line->at(sfBalance) : other->at(sfBalance).
zeroed();
138 return zero ? amt.
zeroed() : amt;
146 auto const balanceBefore = getBalance(before,
after,
false);
153 auto const balanceAfter = getBalance(
after, before, isDelete);
155 return balanceAfter - balanceBefore;
163 "xrpl::TransfersNotFrozen::recordBalance : valid trustline "
168 changes.senders.emplace_back(std::move(change));
172 changes.receivers.emplace_back(std::move(change));
179 auto const balanceChangeSign = balanceChange.
signum();
180 auto const currency =
after->at(sfBalance).get<
Issue>().currency;
184 {currency,
after->at(sfHighLimit).getIssuer()},
185 {.line =
after, .balanceChangeSign = balanceChangeSign});
189 {currency,
after->at(sfLowLimit).getIssuer()},
190 {.line =
after, .balanceChangeSign = -balanceChangeSign});
217 bool const globalFreeze = issuer->isFlag(lsfGlobalFreeze);
232 for (
auto const& change : actors)
234 bool const high = change.line->at(sfLowLimit).getIssuer() == issuer->at(sfAccount);
256 bool const deepFreeze = change.
line->isFlag(high ? lsfLowDeepFreeze : lsfHighDeepFreeze);
257 bool const frozen = globalFreeze || deepFreeze || freeze;
259 bool const isAMMLine = change.
line->isFlag(lsfAMMNode);
269 JLOG(j.
debug()) <<
"Invariant check allowing funds to be moved "
275 JLOG(j.
fatal()) <<
"Invariant failed: Attempting to move frozen funds for "
280 "xrpl::TransfersNotFrozen::validateFrozenState : enforce "
A generic endpoint for log messages.
A currency issued by an account.
virtual Rules const & rules() const =0
Returns the tx processing rules.
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
int signum() const noexcept
STAmount zeroed() const
Returns a zero value with the same issuer and currency.
std::shared_ptr< STLedgerEntry const > const & const_ref
std::shared_ptr< STLedgerEntry const > const_pointer
uint256 getTransactionID() const
void recordBalance(Issue const &issue, BalanceChange change)
std::map< AccountID, SLE::const_pointer const > possibleIssuers_
static STAmount calculateBalanceChange(SLE::const_ref before, SLE::const_ref after, bool isDelete)
void recordBalanceChanges(SLE::const_ref after, STAmount const &balanceChange)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
static bool validateFrozenState(BalanceChange const &change, bool high, STTx const &tx, beast::Journal const &j, bool enforce, bool globalFreeze)
bool isValidEntry(SLE::const_ref before, SLE::const_ref after)
static bool validateIssuerChanges(SLE::const_ref issuer, IssuerChanges const &changes, STTx const &tx, beast::Journal const &j, bool enforce)
void visitEntry(bool, SLE::const_ref, SLE::const_ref)
SLE::const_pointer findIssuer(AccountID const &issuerID, ReadView const &view)
Keylet account(AccountID const &id) noexcept
AccountID root.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool hasPrivilege(STTx const &tx, Privilege priv)
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
TERSubset< CanCvtToTER > TER
SLE::const_pointer const line
int const balanceChangeSign
std::vector< BalanceChange > senders
std::vector< BalanceChange > receivers