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/overlay/PeerSet.h>
21 #include <ripple/app/main/Application.h>
22 #include <ripple/core/JobQueue.h>
23 #include <ripple/overlay/Overlay.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  std::chrono::milliseconds interval, clock_type& clock,
40  beast::Journal journal)
41  : app_ (app)
42  , m_journal (journal)
43  , m_clock (clock)
44  , mHash (hash)
45  , mTimerInterval (interval)
46  , mTimeouts (0)
47  , mComplete (false)
48  , mFailed (false)
49  , mProgress (false)
50  , mTimer (app_.getIOService ())
51 {
53  assert ((mTimerInterval > 10ms) && (mTimerInterval < 30s));
54 }
55 
56 PeerSet::~PeerSet() = default;
57 
59 {
60  ScopedLockType sl (mLock);
61 
62  if (!mPeers.insert (ptr->id ()).second)
63  return false;
64 
65  newPeer (ptr);
66  return true;
67 }
68 
70 {
71  mTimer.expires_from_now(mTimerInterval);
72  mTimer.async_wait (
73  [wptr=pmDowncast()](boost::system::error_code const& ec)
74  {
75  if (ec == boost::asio::error::operation_aborted)
76  return;
77 
78  if (auto ptr = wptr.lock ())
79  ptr->execute ();
80  });
81 }
82 
84 {
85  ScopedLockType sl (mLock);
86 
87  if (isDone ())
88  return;
89 
90  if (!isProgress())
91  {
92  ++mTimeouts;
93  JLOG (m_journal.debug()) << "Timeout(" << mTimeouts
94  << ") pc=" << mPeers.size () << " acquiring " << mHash;
95  onTimer (false, sl);
96  }
97  else
98  {
99  mProgress = false;
100  onTimer (true, sl);
101  }
102 
103  if (!isDone ())
104  setTimer ();
105 }
106 
108 {
109  ScopedLockType sl (mLock);
110  return !isDone ();
111 }
112 
113 void PeerSet::sendRequest (const protocol::TMGetLedger& tmGL, std::shared_ptr<Peer> const& peer)
114 {
115  if (!peer)
116  sendRequest (tmGL);
117  else
118  peer->send (std::make_shared<Message> (tmGL, protocol::mtGET_LEDGER));
119 }
120 
121 void PeerSet::sendRequest (const protocol::TMGetLedger& tmGL)
122 {
123  ScopedLockType sl (mLock);
124 
125  if (mPeers.empty ())
126  return;
127 
128  auto packet = std::make_shared<Message>(tmGL, protocol::mtGET_LEDGER);
129 
130  for (auto id : mPeers)
131  {
132  if (auto peer = app_.overlay ().findPeerByShortID (id))
133  peer->send (packet);
134  }
135 }
136 
138 {
139  std::size_t ret (0);
140 
141  for (auto id : mPeers)
142  {
143  if (app_.overlay ().findPeerByShortID (id))
144  ++ret;
145  }
146 
147  return ret;
148 }
149 
150 } // ripple
ripple::Application
Definition: Application.h:85
std::shared_ptr
STL class.
ripple::PeerSet::onTimer
virtual void onTimer(bool progress, ScopedLockType &)=0
ripple::PeerSet::mProgress
bool mProgress
Definition: PeerSet.h:165
ripple::PeerSet::getPeerCount
std::size_t getPeerCount() const
Definition: PeerSet.cpp:137
ripple::PeerSet::invokeOnTimer
void invokeOnTimer()
Definition: PeerSet.cpp:83
ripple::PeerSet::mTimer
boost::asio::basic_waitable_timer< std::chrono::steady_clock > mTimer
Definition: PeerSet.h:168
ripple::PeerSet::mPeers
std::set< Peer::id_t > mPeers
Definition: PeerSet.h:171
ripple::PeerSet::mHash
uint256 mHash
Definition: PeerSet.h:159
std::chrono::milliseconds
ripple::PeerSet::isDone
virtual bool isDone() const
Definition: PeerSet.h:101
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:58
ripple::PeerSet::m_clock
clock_type & m_clock
Definition: PeerSet.h:155
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:60
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:107
ripple::PeerSet::sendRequest
void sendRequest(const protocol::TMGetLedger &message)
Definition: PeerSet.cpp:121
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:153
ripple::Application::overlay
virtual Overlay & overlay()=0
ripple::PeerSet::mTimerInterval
std::chrono::milliseconds mTimerInterval
Definition: PeerSet.h:160
ripple::PeerSet::mLastAction
clock_type::time_point mLastAction
Definition: PeerSet.h:164
ripple::PeerSet::m_journal
beast::Journal m_journal
Definition: PeerSet.h:154
beast::Journal::debug
Stream debug() const
Definition: Journal.h:292
std::size_t
ripple::PeerSet::mTimeouts
int mTimeouts
Definition: PeerSet.h:161
ripple::PeerSet::pmDowncast
virtual std::weak_ptr< PeerSet > pmDowncast()=0
ripple::PeerSet::isProgress
bool isProgress()
Definition: PeerSet.h:128
ripple::PeerSet::setTimer
void setTimer()
Definition: PeerSet.cpp:69
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:157