rippled
Loading...
Searching...
No Matches
CancelCheck.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2017 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 <xrpld/app/ledger/Ledger.h>
21#include <xrpld/app/tx/detail/CancelCheck.h>
22
23#include <xrpl/basics/Log.h>
24#include <xrpl/ledger/ApplyView.h>
25#include <xrpl/protocol/Feature.h>
26#include <xrpl/protocol/Indexes.h>
27#include <xrpl/protocol/TER.h>
28#include <xrpl/protocol/TxFlags.h>
29
30namespace ripple {
31
34{
35 return tesSUCCESS;
36}
37
38TER
40{
41 auto const sleCheck = ctx.view.read(keylet::check(ctx.tx[sfCheckID]));
42 if (!sleCheck)
43 {
44 JLOG(ctx.j.warn()) << "Check does not exist.";
45 return tecNO_ENTRY;
46 }
47
48 using duration = NetClock::duration;
49 using timepoint = NetClock::time_point;
50 auto const optExpiry = (*sleCheck)[~sfExpiration];
51
52 // Expiration is defined in terms of the close time of the parent
53 // ledger, because we definitively know the time that it closed but
54 // we do not know the closing time of the ledger that is under
55 // construction.
56 if (!optExpiry ||
57 (ctx.view.parentCloseTime() < timepoint{duration{*optExpiry}}))
58 {
59 // If the check is not yet expired, then only the creator or the
60 // destination may cancel the check.
61 AccountID const acctId{ctx.tx[sfAccount]};
62 if (acctId != (*sleCheck)[sfAccount] &&
63 acctId != (*sleCheck)[sfDestination])
64 {
65 JLOG(ctx.j.warn()) << "Check is not expired and canceler is "
66 "neither check source nor destination.";
67 return tecNO_PERMISSION;
68 }
69 }
70 return tesSUCCESS;
71}
72
73TER
74CancelCheck::doApply()
75{
76 auto const sleCheck = view().peek(keylet::check(ctx_.tx[sfCheckID]));
77 if (!sleCheck)
78 {
79 // Error should have been caught in preclaim.
80 JLOG(j_.warn()) << "Check does not exist.";
81 return tecNO_ENTRY;
82 }
83
84 AccountID const srcId{sleCheck->getAccountID(sfAccount)};
85 AccountID const dstId{sleCheck->getAccountID(sfDestination)};
86 auto viewJ = ctx_.app.journal("View");
87
88 // If the check is not written to self (and it shouldn't be), remove the
89 // check from the destination account root.
90 if (srcId != dstId)
91 {
92 std::uint64_t const page{(*sleCheck)[sfDestinationNode]};
93 if (!view().dirRemove(
94 keylet::ownerDir(dstId), page, sleCheck->key(), true))
95 {
96 JLOG(j_.fatal()) << "Unable to delete check from destination.";
97 return tefBAD_LEDGER;
98 }
99 }
100 {
101 std::uint64_t const page{(*sleCheck)[sfOwnerNode]};
102 if (!view().dirRemove(
103 keylet::ownerDir(srcId), page, sleCheck->key(), true))
104 {
105 JLOG(j_.fatal()) << "Unable to delete check from owner.";
106 return tefBAD_LEDGER;
107 }
108 }
109
110 // If we succeeded, update the check owner's reserve.
111 auto const sleSrc = view().peek(keylet::account(srcId));
112 adjustOwnerCount(view(), sleSrc, -1, viewJ);
113
114 // Remove check from ledger.
115 view().erase(sleCheck);
116 return tesSUCCESS;
117}
118
119} // namespace ripple
Stream fatal() const
Definition Journal.h:352
Stream warn() const
Definition Journal.h:340
static TER preclaim(PreclaimContext const &ctx)
static NotTEC preflight(PreflightContext const &ctx)
std::chrono::time_point< NetClock > time_point
Definition chrono.h:69
std::chrono::duration< rep, period > duration
Definition chrono.h:68
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
NetClock::time_point parentCloseTime() const
Returns the close time of the previous ledger.
Definition ReadView.h:111
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Definition Indexes.cpp:336
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Definition View.cpp:1029
@ tefBAD_LEDGER
Definition TER.h:170
@ tecNO_ENTRY
Definition TER.h:306
@ tecNO_PERMISSION
Definition TER.h:305
@ tesSUCCESS
Definition TER.h:244
TERSubset< CanCvtToTER > TER
Definition TER.h:645
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:605
uint256 key
Definition Keylet.h:40
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:80
ReadView const & view
Definition Transactor.h:83
beast::Journal const j
Definition Transactor.h:88
State information when preflighting a tx.
Definition Transactor.h:35