rippled
PeerSet.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/main/Application.h>
21 #include <ripple/core/JobQueue.h>
22 #include <ripple/overlay/Overlay.h>
23 #include <ripple/overlay/PeerSet.h>
24 
25 namespace ripple {
26 
27 using namespace std::chrono_literals;
28 
29 class InboundLedger;
30 
31 // VFALCO NOTE The txnData constructor parameter is a code smell.
32 // It is true if we are the base of a TransactionAcquire,
33 // or false if we are base of InboundLedger. All it does
34 // is change the behavior of the timer depending on the
35 // derived class. Why not just make the timer callback
36 // function pure virtual?
37 //
39  Application& app,
40  uint256 const& hash,
42  clock_type& clock,
43  beast::Journal journal)
44  : app_(app)
45  , m_journal(journal)
46  , m_clock(clock)
47  , mHash(hash)
48  , mTimerInterval(interval)
49  , mTimeouts(0)
50  , mComplete(false)
51  , mFailed(false)
52  , mProgress(false)
53  , mTimer(app_.getIOService())
54 {
56  assert((mTimerInterval > 10ms) && (mTimerInterval < 30s));
57 }
58 
59 PeerSet::~PeerSet() = default;
60 
61 bool
63 {
65 
66  if (!mPeers.insert(ptr->id()).second)
67  return false;
68 
69  newPeer(ptr);
70  return true;
71 }
72 
73 void
75 {
76  mTimer.expires_from_now(mTimerInterval);
77  mTimer.async_wait(
78  [wptr = pmDowncast()](boost::system::error_code const& ec) {
79  if (ec == boost::asio::error::operation_aborted)
80  return;
81 
82  if (auto ptr = wptr.lock())
83  ptr->execute();
84  });
85 }
86 
87 void
89 {
91 
92  if (isDone())
93  return;
94 
95  if (!isProgress())
96  {
97  ++mTimeouts;
98  JLOG(m_journal.debug())
99  << "Timeout(" << mTimeouts << ") pc=" << mPeers.size()
100  << " acquiring " << mHash;
101  onTimer(false, sl);
102  }
103  else
104  {
105  mProgress = false;
106  onTimer(true, sl);
107  }
108 
109  if (!isDone())
110  setTimer();
111 }
112 
113 bool
115 {
116  ScopedLockType sl(mLock);
117  return !isDone();
118 }
119 
120 void
122  const protocol::TMGetLedger& tmGL,
123  std::shared_ptr<Peer> const& peer)
124 {
125  if (!peer)
126  sendRequest(tmGL);
127  else
128  peer->send(std::make_shared<Message>(tmGL, protocol::mtGET_LEDGER));
129 }
130 
131 void
132 PeerSet::sendRequest(const protocol::TMGetLedger& tmGL)
133 {
134  ScopedLockType sl(mLock);
135 
136  if (mPeers.empty())
137  return;
138 
139  auto packet = std::make_shared<Message>(tmGL, protocol::mtGET_LEDGER);
140 
141  for (auto id : mPeers)
142  {
143  if (auto peer = app_.overlay().findPeerByShortID(id))
144  peer->send(packet);
145  }
146 }
147 
150 {
151  std::size_t ret(0);
152 
153  for (auto id : mPeers)
154  {
155  if (app_.overlay().findPeerByShortID(id))
156  ++ret;
157  }
158 
159  return ret;
160 }
161 
162 } // namespace ripple
ripple::Application
Definition: Application.h:94
std::shared_ptr
STL class.
ripple::PeerSet::onTimer
virtual void onTimer(bool progress, ScopedLockType &)=0
ripple::PeerSet::mProgress
bool mProgress
Definition: PeerSet.h:193
ripple::PeerSet::getPeerCount
std::size_t getPeerCount() const
Definition: PeerSet.cpp:149
ripple::PeerSet::invokeOnTimer
void invokeOnTimer()
Definition: PeerSet.cpp:88
ripple::PeerSet::mTimer
boost::asio::basic_waitable_timer< std::chrono::steady_clock > mTimer
Definition: PeerSet.h:196
ripple::PeerSet::mPeers
std::set< Peer::id_t > mPeers
Definition: PeerSet.h:199
ripple::PeerSet::mHash
uint256 mHash
Definition: PeerSet.h:187
std::chrono::milliseconds
ripple::PeerSet::isDone
virtual bool isDone() const
Definition: PeerSet.h:111
ripple::PeerSet::newPeer
virtual void newPeer(std::shared_ptr< Peer > const &)=0
ripple::PeerSet::insert
bool insert(std::shared_ptr< Peer > const &)
Insert a peer to the managed set.
Definition: PeerSet.cpp:62
ripple::PeerSet::m_clock
clock_type & m_clock
Definition: PeerSet.h:183
beast::abstract_clock::now
virtual time_point now() const =0
Returns the current time.
ripple::base_uint< 256 >
ripple::PeerSet::~PeerSet
virtual ~PeerSet()=0
std::unique_lock
STL class.
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::PeerSet::PeerSet
PeerSet(Application &app, uint256 const &hash, std::chrono::milliseconds interval, clock_type &clock, beast::Journal journal)
Definition: PeerSet.cpp:38
beast::abstract_clock< std::chrono::steady_clock >
ripple::PeerSet::isActive
bool isActive()
Definition: PeerSet.cpp:114
ripple::PeerSet::sendRequest
void sendRequest(const protocol::TMGetLedger &message)
Definition: PeerSet.cpp:132
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::PeerSet::app_
Application & app_
Definition: PeerSet.h:181
ripple::Application::overlay
virtual Overlay & overlay()=0
ripple::PeerSet::mTimerInterval
std::chrono::milliseconds mTimerInterval
Definition: PeerSet.h:188
ripple::PeerSet::mLastAction
clock_type::time_point mLastAction
Definition: PeerSet.h:192
ripple::PeerSet::m_journal
beast::Journal m_journal
Definition: PeerSet.h:182
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
std::size_t
ripple::PeerSet::mTimeouts
int mTimeouts
Definition: PeerSet.h:189
ripple::PeerSet::pmDowncast
virtual std::weak_ptr< PeerSet > pmDowncast()=0
ripple::PeerSet::isProgress
bool isProgress()
Definition: PeerSet.h:147
ripple::PeerSet::setTimer
void setTimer()
Definition: PeerSet.cpp:74
ripple::Overlay::findPeerByShortID
virtual std::shared_ptr< Peer > findPeerByShortID(Peer::id_t const &id)=0
Returns the peer with the matching short id, or null.
ripple::PeerSet::mLock
std::recursive_mutex mLock
Definition: PeerSet.h:185