rippled
OpenLedger.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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/OpenLedger.h>
21 #include <ripple/app/main/Application.h>
22 #include <ripple/app/misc/HashRouter.h>
23 #include <ripple/app/misc/TxQ.h>
24 #include <ripple/app/tx/apply.h>
25 #include <ripple/ledger/CachedView.h>
26 #include <ripple/overlay/Message.h>
27 #include <ripple/overlay/Overlay.h>
28 #include <ripple/overlay/predicates.h>
29 #include <ripple/protocol/Feature.h>
30 #include <boost/range/adaptor/transformed.hpp>
31 
32 namespace ripple {
33 
35  std::shared_ptr<Ledger const> const& ledger,
36  CachedSLEs& cache,
37  beast::Journal journal)
38  : j_(journal), cache_(cache), current_(create(ledger->rules(), ledger))
39 {
40 }
41 
42 bool
44 {
46  return current_->txCount() == 0;
47 }
48 
51 {
53  return current_;
54 }
55 
56 bool
58 {
60  auto next = std::make_shared<OpenView>(*current_);
61  auto const changed = f(*next, j_);
62  if (changed)
63  {
65  current_ = std::move(next);
66  }
67  return changed;
68 }
69 
70 void
72  Application& app,
73  Rules const& rules,
74  std::shared_ptr<Ledger const> const& ledger,
75  OrderedTxs const& locals,
76  bool retriesFirst,
77  OrderedTxs& retries,
78  ApplyFlags flags,
79  std::string const& suffix,
80  modify_type const& f)
81 {
82  JLOG(j_.trace()) << "accept ledger " << ledger->seq() << " " << suffix;
83  auto next = create(rules, ledger);
84  if (retriesFirst)
85  {
86  // Handle disputed tx, outside lock
88  apply(app, *next, *ledger, empty{}, retries, flags, j_);
89  }
90  // Block calls to modify, otherwise
91  // new tx going into the open ledger
92  // would get lost.
94  // Apply tx from the current open view
95  if (!current_->txs.empty())
96  {
97  apply(
98  app,
99  *next,
100  *ledger,
101  boost::adaptors::transform(
102  current_->txs,
103  [](std::pair<
106  return p.first;
107  }),
108  retries,
109  flags,
110  j_);
111  }
112  // Call the modifier
113  if (f)
114  f(*next, j_);
115  // Apply local tx
116  for (auto const& item : locals)
117  app.getTxQ().apply(app, *next, item.second, flags, j_);
118 
119  // If we didn't relay this transaction recently, relay it to all peers
120  for (auto const& txpair : next->txs)
121  {
122  auto const& tx = txpair.first;
123  auto const txId = tx->getTransactionID();
124  if (auto const toSkip = app.getHashRouter().shouldRelay(txId))
125  {
126  JLOG(j_.debug()) << "Relaying recovered tx " << txId;
127  protocol::TMTransaction msg;
128  Serializer s;
129 
130  tx->add(s);
131  msg.set_rawtransaction(s.data(), s.size());
132  msg.set_status(protocol::tsNEW);
133  msg.set_receivetimestamp(
134  app.timeKeeper().now().time_since_epoch().count());
135  app.overlay().relay(txId, msg, *toSkip);
136  }
137  }
138 
139  // Switch to the new open view
141  current_ = std::move(next);
142 }
143 
144 //------------------------------------------------------------------------------
145 
148  Rules const& rules,
149  std::shared_ptr<Ledger const> const& ledger)
150 {
151  return std::make_shared<OpenView>(
152  open_ledger,
153  rules,
154  std::make_shared<CachedLedger const>(ledger, cache_));
155 }
156 
157 auto
159  Application& app,
160  OpenView& view,
161  std::shared_ptr<STTx const> const& tx,
162  bool retry,
163  ApplyFlags flags,
164  beast::Journal j) -> Result
165 {
166  if (retry)
167  flags = flags | tapRETRY;
168  // If it's in anybody's proposed set, try to keep it in the ledger
169  auto const result = ripple::apply(app, view, *tx, flags, j);
170  if (result.second || result.first == terQUEUED)
171  return Result::success;
172  if (isTefFailure(result.first) || isTemMalformed(result.first) ||
173  isTelLocal(result.first))
174  return Result::failure;
175  return Result::retry;
176 }
177 
178 //------------------------------------------------------------------------------
179 
182 {
184  ss << tx->getTransactionID();
185  return ss.str().substr(0, 4);
186 }
187 
190 {
192  for (auto const& item : set)
193  ss << debugTxstr(item.second) << ", ";
194  return ss.str();
195 }
196 
199 {
201  for (auto const& item : set)
202  {
203  try
204  {
205  SerialIter sit(item.slice());
206  auto const tx = std::make_shared<STTx const>(sit);
207  ss << debugTxstr(tx) << ", ";
208  }
209  catch (std::exception const& ex)
210  {
211  ss << "THROW:" << ex.what() << ", ";
212  }
213  }
214  return ss.str();
215 }
216 
219 {
221  for (auto const& item : view->txs)
222  ss << debugTxstr(item.first) << ", ";
223  return ss.str();
224 }
225 
226 } // namespace ripple
ripple::Application
Definition: Application.h:115
ripple::OpenLedger::current
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
Definition: OpenLedger.cpp:50
std::string
STL class.
std::shared_ptr
STL class.
ripple::TaggedCache< uint256, SLE const >
std::exception
STL class.
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::OpenLedger::current_
std::shared_ptr< OpenView const > current_
Definition: OpenLedger.h:56
ripple::apply
std::pair< TER, bool > apply(Application &app, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
Definition: apply.cpp:109
ripple::open_ledger
const open_ledger_t open_ledger
Definition: OpenView.cpp:25
std::pair
ripple::TxQ::apply
std::pair< TER, bool > apply(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, ApplyFlags flags, beast::Journal j)
Add a new transaction to the open ledger, hold it in the queue, or reject it.
Definition: TxQ.cpp:713
ripple::OpenView
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:55
std::vector
STL class.
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:29
std::stringstream
STL class.
std::lock_guard
STL class.
std::function
ripple::Application::timeKeeper
virtual TimeKeeper & timeKeeper()=0
ripple::OpenLedger::modify_mutex_
std::mutex modify_mutex_
Definition: OpenLedger.h:54
ripple::OpenLedger::apply
static void apply(Application &app, OpenView &view, ReadView const &check, FwdRange const &txs, OrderedTxs &retries, ApplyFlags flags, beast::Journal j)
Algorithm for applying transactions.
Definition: OpenLedger.h:209
ripple::OpenLedger::accept
void accept(Application &app, Rules const &rules, std::shared_ptr< Ledger const > const &ledger, OrderedTxs const &locals, bool retriesFirst, OrderedTxs &retries, ApplyFlags flags, std::string const &suffix="", modify_type const &f={})
Accept a new ledger.
Definition: OpenLedger.cpp:71
ripple::CanonicalTXSet
Holds transactions which were deferred to the next pass of consensus.
Definition: CanonicalTXSet.h:38
ripple::Serializer::data
void const * data() const noexcept
Definition: Serializer.h:75
ripple::terQUEUED
@ terQUEUED
Definition: TER.h:206
ripple::OpenLedger::j_
const beast::Journal j_
Definition: OpenLedger.h:52
ripple::isTefFailure
bool isTefFailure(TER x)
Definition: TER.h:585
ripple::OpenLedger::OpenLedger
OpenLedger()=delete
ripple::SHAMap
A SHAMap is both a radix tree with a fan-out of 16 and a Merkle tree.
Definition: SHAMap.h:95
ripple::Application::getTxQ
virtual TxQ & getTxQ()=0
ripple::set
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
Definition: BasicConfig.h:313
ripple::SerialIter
Definition: Serializer.h:310
ripple::debugTxstr
std::string debugTxstr(std::shared_ptr< STTx const > const &tx)
Definition: OpenLedger.cpp:181
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::Overlay::relay
virtual std::set< Peer::id_t > relay(protocol::TMProposeSet &m, uint256 const &uid, PublicKey const &validator)=0
Relay a proposal.
ripple::HashRouter::shouldRelay
std::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
Definition: HashRouter.cpp:118
ripple::debugTostr
std::string debugTostr(OrderedTxs const &set)
Definition: OpenLedger.cpp:189
ripple::OpenLedger::empty
bool empty() const
Returns true if there are no transactions.
Definition: OpenLedger.cpp:43
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:191
ripple::tapRETRY
@ tapRETRY
Definition: ApplyView.h:38
ripple::Serializer
Definition: Serializer.h:39
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::OpenLedger::apply_one
static Result apply_one(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, bool retry, ApplyFlags flags, beast::Journal j)
Definition: OpenLedger.cpp:158
ripple::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:69
ripple::OpenLedger::cache_
CachedSLEs & cache_
Definition: OpenLedger.h:53
ripple::isTelLocal
bool isTelLocal(TER x)
Definition: TER.h:573
ripple::TimeKeeper::now
virtual time_point now() const override=0
Returns the estimate of wall time, in network time.
ripple::Application::overlay
virtual Overlay & overlay()=0
ripple::Rules
Rules controlling protocol behavior.
Definition: Rules.h:33
std::stringstream::str
T str(T... args)
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::OpenLedger::Result
Result
Definition: OpenLedger.h:190
ripple::OpenLedger::create
std::shared_ptr< OpenView > create(Rules const &rules, std::shared_ptr< Ledger const > const &ledger)
Definition: OpenLedger.cpp:147
ripple::OpenLedger::current_mutex_
std::mutex current_mutex_
Definition: OpenLedger.h:55
ripple::Application::getHashRouter
virtual HashRouter & getHashRouter()=0
ripple::OpenLedger::modify
bool modify(modify_type const &f)
Modify the open ledger.
Definition: OpenLedger.cpp:57
ripple::isTemMalformed
bool isTemMalformed(TER x)
Definition: TER.h:579
std::exception::what
T what(T... args)
ripple::ReadView::txs
txs_type txs
Definition: ReadView.h:323