xrpld
Loading...
Searching...
No Matches
CheckCancel.cpp
1#include <xrpl/tx/transactors/check/CheckCancel.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/beast/utility/Zero.h>
5#include <xrpl/ledger/ApplyView.h>
6#include <xrpl/ledger/View.h>
7#include <xrpl/ledger/helpers/AccountRootHelpers.h>
8#include <xrpl/protocol/AccountID.h>
9#include <xrpl/protocol/Feature.h>
10#include <xrpl/protocol/Indexes.h>
11#include <xrpl/protocol/SField.h>
12#include <xrpl/protocol/STLedgerEntry.h>
13#include <xrpl/protocol/STTx.h>
14#include <xrpl/protocol/TER.h>
15#include <xrpl/protocol/XRPAmount.h>
16#include <xrpl/tx/Transactor.h>
17
18#include <cstdint>
19namespace xrpl {
20
23{
24 if (ctx.rules.enabled(fixCleanup3_3_0) && ctx.tx[sfCheckID] == beast::kZero)
25 return temMALFORMED;
26
27 return tesSUCCESS;
28}
29
30TER
32{
33 auto const sleCheck = ctx.view.read(keylet::check(ctx.tx[sfCheckID]));
34 if (!sleCheck)
35 {
36 JLOG(ctx.j.warn()) << "Check does not exist.";
37 return tecNO_ENTRY;
38 }
39
40 // Expiration is defined in terms of the close time of the parent
41 // ledger, because we definitively know the time that it closed but
42 // we do not know the closing time of the ledger that is under
43 // construction.
44 if (!hasExpired(ctx.view, (*sleCheck)[~sfExpiration]))
45 {
46 // If the check is not yet expired, then only the creator or the
47 // destination may cancel the check.
48 AccountID const acctId{ctx.tx[sfAccount]};
49 if (acctId != (*sleCheck)[sfAccount] && acctId != (*sleCheck)[sfDestination])
50 {
51 JLOG(ctx.j.warn()) << "Check is not expired and canceler is "
52 "neither check source nor destination.";
53 return tecNO_PERMISSION;
54 }
55 }
56 return tesSUCCESS;
57}
58
59TER
61{
62 auto const sleCheck = view().peek(keylet::check(ctx_.tx[sfCheckID]));
63 if (!sleCheck)
64 {
65 // Error should have been caught in preclaim.
66 JLOG(j_.warn()) << "Check does not exist.";
67 return tecNO_ENTRY;
68 }
69
70 AccountID const srcId{sleCheck->getAccountID(sfAccount)};
71 AccountID const dstId{sleCheck->getAccountID(sfDestination)};
72 auto viewJ = ctx_.registry.get().getJournal("View");
73
74 // If the check is not written to self (and it shouldn't be), remove the
75 // check from the destination account root.
76 if (srcId != dstId)
77 {
78 std::uint64_t const page{(*sleCheck)[sfDestinationNode]};
79 if (!view().dirRemove(keylet::ownerDir(dstId), page, sleCheck->key(), true))
80 {
81 // LCOV_EXCL_START
82 JLOG(j_.fatal()) << "Unable to delete check from destination.";
83 return tefBAD_LEDGER;
84 // LCOV_EXCL_STOP
85 }
86 }
87 {
88 std::uint64_t const page{(*sleCheck)[sfOwnerNode]};
89 if (!view().dirRemove(keylet::ownerDir(srcId), page, sleCheck->key(), true))
90 {
91 // LCOV_EXCL_START
92 JLOG(j_.fatal()) << "Unable to delete check from owner.";
93 return tefBAD_LEDGER;
94 // LCOV_EXCL_STOP
95 }
96 }
97
98 // If we succeeded, update the check owner's reserve.
99 decreaseOwnerCountForObject(view(), srcId, sleCheck, 1, viewJ);
100
101 // Remove check from ledger.
102 view().erase(sleCheck);
103 return tesSUCCESS;
104}
105
106void
108{
109 // No transaction-specific invariants yet (future work).
110}
111
112bool
114{
115 // No transaction-specific invariants yet (future work).
116 return true;
117}
118
119} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:44
Stream warn() const
Definition Journal.h:356
virtual SLE::pointer peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual void erase(SLE::ref sle)=0
Remove a peeked SLE.
static TER preclaim(PreclaimContext const &ctx)
bool finalizeInvariants(STTx const &tx, TER result, XRPAmount fee, ReadView const &view, beast::Journal const &j) override
Check transaction-specific post-conditions after all entries have been visited.
static NotTEC preflight(PreflightContext const &ctx)
void visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override
Inspect a single ledger entry modified by this transaction.
TER doApply() override
A view into a ledger.
Definition ReadView.h:41
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.
Definition Rules.cpp:180
std::shared_ptr< STLedgerEntry const > const & const_ref
beast::Journal const j_
Definition Transactor.h:155
ApplyView & view()
Definition Transactor.h:175
ApplyContext & ctx_
Definition Transactor.h:153
constexpr Zero kZero
Definition Zero.h:30
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:373
Keylet check(AccountID const &id, SeqProxy const &seq) noexcept
A Check.
Definition Indexes.cpp:338
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
void decreaseOwnerCountForObject(ApplyView &view, SLE::ref accountSle, SLE::ref objectSle, std::uint32_t count, beast::Journal j)
Decrease owner-count fields for an existing ledger object.
bool hasExpired(ReadView const &view, std::optional< std::uint32_t > const &exp, ExpiryComparison comparison=ExpiryComparison::Inclusive)
Determines whether the given expiration time has passed.
Definition View.cpp:48
@ tefBAD_LEDGER
Definition TER.h:162
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:607
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
@ temMALFORMED
Definition TER.h:75
TERSubset< CanCvtToTER > TER
Definition TER.h:647
@ tecNO_ENTRY
Definition TER.h:309
@ tecNO_PERMISSION
Definition TER.h:308
@ tesSUCCESS
Definition TER.h:245
uint256 key
Definition Keylet.h:21
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:83
ReadView const & view
Definition Transactor.h:86
beast::Journal const j
Definition Transactor.h:91
State information when preflighting a tx.
Definition Transactor.h:38