rippled
CreateTicket.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2014 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/ledger/Ledger.h>
21 #include <ripple/app/tx/impl/CreateTicket.h>
22 #include <ripple/basics/Log.h>
23 #include <ripple/protocol/Feature.h>
24 #include <ripple/protocol/Indexes.h>
25 #include <ripple/protocol/TxFlags.h>
26 
27 namespace ripple {
28 
29 NotTEC
31 {
32  if (!ctx.rules.enabled(featureTickets))
33  return temDISABLED;
34 
35  if (ctx.tx.getFlags() & tfUniversalMask)
36  return temINVALID_FLAG;
37 
38  auto const ret = preflight1(ctx);
39  if (!isTesSuccess(ret))
40  return ret;
41 
43  {
44  if (ctx.tx.getFieldU32(sfExpiration) == 0)
45  {
46  JLOG(ctx.j.warn()) << "Malformed transaction: bad expiration";
47  return temBAD_EXPIRATION;
48  }
49  }
50 
51  return preflight2(ctx);
52 }
53 
54 TER
56 {
57  auto const sle = view().peek(keylet::account(account_));
58  if (!sle)
59  return tefINTERNAL;
60 
61  // A ticket counts against the reserve of the issuing account, but we
62  // check the starting balance because we want to allow dipping into the
63  // reserve to pay fees.
64  {
65  auto const reserve =
66  view().fees().accountReserve(sle->getFieldU32(sfOwnerCount) + 1);
67 
68  if (mPriorBalance < reserve)
70  }
71 
72  NetClock::time_point expiration{};
73 
75  {
76  expiration =
78 
79  if (view().parentCloseTime() >= expiration)
80  return tesSUCCESS;
81  }
82 
83  SLE::pointer sleTicket = std::make_shared<SLE>(
85  sleTicket->setAccountID(sfAccount, account_);
86  sleTicket->setFieldU32(sfSequence, ctx_.tx.getSequence());
87  if (expiration != NetClock::time_point{})
88  sleTicket->setFieldU32(
89  sfExpiration, expiration.time_since_epoch().count());
90  view().insert(sleTicket);
91 
93  {
94  AccountID const target_account(ctx_.tx.getAccountID(sfTarget));
95 
96  SLE::pointer sleTarget = view().peek(keylet::account(target_account));
97 
98  // Destination account does not exist.
99  if (!sleTarget)
100  return tecNO_TARGET;
101 
102  // The issuing account is the default account to which the ticket
103  // applies so don't bother saving it if that's what's specified.
104  if (target_account != account_)
105  sleTicket->setAccountID(sfTarget, target_account);
106  }
107 
108  auto viewJ = ctx_.app.journal("View");
109 
110  auto const page = dirAdd(
111  view(),
113  sleTicket->key(),
114  false,
116  viewJ);
117 
118  JLOG(j_.trace()) << "Creating ticket " << to_string(sleTicket->key())
119  << ": " << (page ? "success" : "failure");
120 
121  if (!page)
122  return tecDIR_FULL;
123 
124  sleTicket->setFieldU64(sfOwnerNode, *page);
125 
126  // If we succeeded, the new entry counts against the
127  // creator's reserve.
128  adjustOwnerCount(view(), sle, 1, viewJ);
129  return tesSUCCESS;
130 }
131 
132 } // namespace ripple
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:285
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:90
ripple::tecNO_TARGET
@ tecNO_TARGET
Definition: TER.h:262
ripple::sfTarget
const SF_Account sfTarget(access, STI_ACCOUNT, 7, "Target")
Definition: SField.h:486
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:149
std::shared_ptr< STLedgerEntry >
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
ripple::describeOwnerDir
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition: View.cpp:713
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:90
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:576
ripple::sfSequence
const SF_U32 sfSequence(access, STI_UINT32, 4, "Sequence")
Definition: SField.h:356
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::sfAccount
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
Definition: SField.h:480
std::chrono::duration
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:42
ripple::sfOwnerNode
const SF_U64 sfOwnerNode(access, STI_UINT64, 4, "OwnerNode")
Definition: SField.h:398
ripple::sfOwnerCount
const SF_U32 sfOwnerCount(access, STI_UINT32, 13, "OwnerCount")
Definition: SField.h:365
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:39
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:56
ripple::ltTICKET
@ ltTICKET
Definition: LedgerFormats.h:68
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:47
ripple::base_uint< 160, detail::AccountIDTag >
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:106
ripple::adjustOwnerCount
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:642
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:121
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:562
ripple::TERSubset< CanCvtToTER >
std::chrono::time_point
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:454
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:103
ripple::featureTickets
const uint256 featureTickets
Definition: Feature.cpp:163
ripple::sfExpiration
const SF_U32 sfExpiration(access, STI_UINT32, 10, "Expiration")
Definition: SField.h:362
ripple::STTx::getSequence
std::uint32_t getSequence() const
Definition: STTx.h:117
ripple::tecDIR_FULL
@ tecDIR_FULL
Definition: TER.h:245
ripple::dirAdd
boost::optional< std::uint64_t > dirAdd(ApplyView &view, Keylet const &dir, uint256 const &uLedgerIndex, bool strictOrder, std::function< void(SLE::ref)> fDescriber, beast::Journal j)
Definition: View.cpp:721
ripple::ApplyView::insert
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
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::Transactor::view
ApplyView & view()
Definition: Transactor.h:107
ripple::getTicketIndex
uint256 getTicketIndex(AccountID const &account, std::uint32_t uSequence)
Definition: Indexes.cpp:110
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:109
ripple::Fees::accountReserve
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
Definition: ReadView.h:65
ripple::STObject::isFieldPresent
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:401
ripple::Transactor::mPriorBalance
XRPAmount mPriorBalance
Definition: Transactor.h:93
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:265
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:89
ripple::Transactor::account_
AccountID account_
Definition: Transactor.h:92
ripple::CreateTicket::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: CreateTicket.cpp:30
ripple::tfUniversalMask
const std::uint32_t tfUniversalMask
Definition: TxFlags.h:50
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:36
ripple::STObject::getFieldU32
std::uint32_t getFieldU32(SField const &field) const
Definition: STObject.cpp:532
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:32
ripple::temBAD_EXPIRATION
@ temBAD_EXPIRATION
Definition: TER.h:86
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:37
ripple::NetClock::time_point
std::chrono::time_point< NetClock > time_point
Definition: chrono.h:54
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:213
ripple::CreateTicket::doApply
TER doApply() override
Definition: CreateTicket.cpp:55
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:507