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/tx/impl/CreateTicket.h>
21 #include <ripple/app/ledger/Ledger.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 
42  if (ctx.tx.isFieldPresent (sfExpiration))
43  {
44  if (ctx.tx.getFieldU32 (sfExpiration) == 0)
45  {
46  JLOG(ctx.j.warn()) <<
47  "Malformed transaction: bad expiration";
48  return temBAD_EXPIRATION;
49  }
50  }
51 
52  return preflight2 (ctx);
53 }
54 
55 TER
57 {
58  auto const sle = view().peek(keylet::account(account_));
59  if (! sle)
60  return tefINTERNAL;
61 
62  // A ticket counts against the reserve of the issuing account, but we
63  // check the starting balance because we want to allow dipping into the
64  // reserve to pay fees.
65  {
66  auto const reserve = view().fees().accountReserve(
67  sle->getFieldU32(sfOwnerCount) + 1);
68 
69  if (mPriorBalance < reserve)
71  }
72 
73  NetClock::time_point expiration{};
74 
76  {
78 
79  if (view().parentCloseTime() >= expiration)
80  return tesSUCCESS;
81  }
82 
83  SLE::pointer sleTicket = std::make_shared<SLE>(ltTICKET,
85  sleTicket->setAccountID (sfAccount, account_);
86  sleTicket->setFieldU32 (sfSequence, ctx_.tx.getSequence ());
87  if (expiration != NetClock::time_point{})
88  sleTicket->setFieldU32 (sfExpiration, expiration.time_since_epoch().count());
89  view().insert (sleTicket);
90 
92  {
93  AccountID const target_account (ctx_.tx.getAccountID (sfTarget));
94 
95  SLE::pointer sleTarget = view().peek (keylet::account(target_account));
96 
97  // Destination account does not exist.
98  if (!sleTarget)
99  return tecNO_TARGET;
100 
101  // The issuing account is the default account to which the ticket
102  // applies so don't bother saving it if that's what's specified.
103  if (target_account != account_)
104  sleTicket->setAccountID (sfTarget, target_account);
105  }
106 
107  auto viewJ = ctx_.app.journal ("View");
108 
109  auto const page = dirAdd(view(), keylet::ownerDir (account_),
110  sleTicket->key(), false, describeOwnerDir (account_), viewJ);
111 
112  JLOG(j_.trace()) <<
113  "Creating ticket " << to_string (sleTicket->key()) <<
114  ": " << (page ? "success" : "failure");
115 
116  if (!page)
117  return tecDIR_FULL;
118 
119  sleTicket->setFieldU64(sfOwnerNode, *page);
120 
121  // If we succeeded, the new entry counts against the
122  // creator's reserve.
123  adjustOwnerCount(view(), sle, 1, viewJ);
124  return tesSUCCESS;
125 }
126 
127 }
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:269
ripple::sfTarget
const SF_Account sfTarget(access, STI_ACCOUNT, 7, "Target")
Definition: SField.h:466
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:153
std::shared_ptr< STLedgerEntry >
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:287
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:700
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:82
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:501
ripple::sfSequence
const SF_U32 sfSequence(access, STI_UINT32, 4, "Sequence")
Definition: SField.h:340
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:460
std::chrono::duration
beast::Journal::warn
Stream warn() const
Definition: Journal.h:302
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:41
ripple::sfOwnerNode
const SF_U64 sfOwnerNode(access, STI_UINT64, 4, "OwnerNode")
Definition: SField.h:382
ripple::sfOwnerCount
const SF_U32 sfOwnerCount(access, STI_UINT32, 13, "OwnerCount")
Definition: SField.h:349
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:69
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:44
ripple::base_uint< 160, detail::AccountIDTag >
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:109
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:629
ripple::keylet::account
static const account_t account
Definition: Indexes.h:116
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:537
ripple::TERSubset< CanCvtToTER >
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id)
The root page of an account's directory.
Definition: Indexes.cpp:318
std::chrono::time_point
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:439
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:107
ripple::featureTickets
const uint256 featureTickets
Definition: Feature.cpp:157
ripple::sfExpiration
const SF_U32 sfExpiration(access, STI_UINT32, 10, "Expiration")
Definition: SField.h:346
ripple::STTx::getSequence
std::uint32_t getSequence() const
Definition: STTx.h:108
ripple::tecDIR_FULL
@ tecDIR_FULL
Definition: TER.h:252
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:709
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:98
ripple::getTicketIndex
uint256 getTicketIndex(AccountID const &account, std::uint32_t uSequence)
Definition: Indexes.cpp:142
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:112
ripple::Fees::accountReserve
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
Definition: ReadView.h:64
ripple::STObject::isFieldPresent
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:392
ripple::Transactor::mPriorBalance
XRPAmount mPriorBalance
Definition: Transactor.h:85
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:272
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:81
ripple::Transactor::account_
AccountID account_
Definition: Transactor.h:84
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:512
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:32
ripple::temBAD_EXPIRATION
@ temBAD_EXPIRATION
Definition: TER.h:89
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:37
ripple::NetClock::time_point
std::chrono::time_point< NetClock > time_point
Definition: chrono.h:53
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:219
ripple::CreateTicket::doApply
TER doApply() override
Definition: CreateTicket.cpp:56
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:45
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:461