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 
30  Application& app,
31  uint256 const& hash,
33  beast::Journal journal)
34  : app_(app)
35  , m_journal(journal)
36  , mHash(hash)
37  , mTimeouts(0)
38  , mComplete(false)
39  , mFailed(false)
40  , mProgress(false)
41  , mTimerInterval(interval)
42  , mTimer(app_.getIOService())
43 {
44  assert((mTimerInterval > 10ms) && (mTimerInterval < 30s));
45 }
46 
47 PeerSet::~PeerSet() = default;
48 
49 void
51  std::size_t limit,
52  std::function<bool(std::shared_ptr<Peer> const&)> hasItem)
53 {
54  using ScoredPeer = std::pair<int, std::shared_ptr<Peer>>;
55 
56  auto const& overlay = app_.overlay();
57 
59  pairs.reserve(overlay.size());
60 
61  overlay.foreach([&](auto const& peer) {
62  auto const score = peer->getScore(hasItem(peer));
63  pairs.emplace_back(score, std::move(peer));
64  });
65 
66  std::sort(
67  pairs.begin(),
68  pairs.end(),
69  [](ScoredPeer const& lhs, ScoredPeer const& rhs) {
70  return lhs.first > rhs.first;
71  });
72 
75  for (auto const& pair : pairs)
76  {
77  auto const peer = pair.second;
78  if (!mPeers.insert(peer->id()).second)
79  continue;
80  onPeerAdded(peer);
81  if (++accepted >= limit)
82  break;
83  }
84 }
85 
86 void
88 {
89  mTimer.expires_after(mTimerInterval);
90  mTimer.async_wait(
91  [wptr = pmDowncast()](boost::system::error_code const& ec) {
92  if (ec == boost::asio::error::operation_aborted)
93  return;
94 
95  if (auto ptr = wptr.lock())
96  ptr->queueJob();
97  });
98 }
99 
100 void
102 {
103  ScopedLockType sl(mLock);
104 
105  if (isDone())
106  return;
107 
108  if (!mProgress)
109  {
110  ++mTimeouts;
111  JLOG(m_journal.debug())
112  << "Timeout(" << mTimeouts << ") pc=" << mPeers.size()
113  << " acquiring " << mHash;
114  onTimer(false, sl);
115  }
116  else
117  {
118  mProgress = false;
119  onTimer(true, sl);
120  }
121 
122  if (!isDone())
123  setTimer();
124 }
125 
126 void
128  const protocol::TMGetLedger& tmGL,
129  std::shared_ptr<Peer> const& peer)
130 {
131  auto packet = std::make_shared<Message>(tmGL, protocol::mtGET_LEDGER);
132 
133  if (peer)
134  {
135  peer->send(packet);
136  return;
137  }
138 
139  ScopedLockType sl(mLock);
140 
141  for (auto id : mPeers)
142  {
143  if (auto p = app_.overlay().findPeerByShortID(id))
144  p->send(packet);
145  }
146 }
147 
148 } // namespace ripple
ripple::Application
Definition: Application.h:97
std::shared_ptr
STL class.
ripple::PeerSet::onTimer
virtual void onTimer(bool progress, ScopedLockType &)=0
Hook called from invokeOnTimer().
ripple::PeerSet::mProgress
bool mProgress
Whether forward progress has been made.
Definition: PeerSet.h:117
ripple::PeerSet::isDone
bool isDone() const
Definition: PeerSet.h:84
ripple::PeerSet::invokeOnTimer
void invokeOnTimer()
Calls onTimer() if in the right state.
Definition: PeerSet.cpp:101
std::pair
std::vector::reserve
T reserve(T... args)
ripple::PeerSet::mTimer
boost::asio::basic_waitable_timer< std::chrono::steady_clock > mTimer
Definition: PeerSet.h:126
std::vector
STL class.
ripple::PeerSet::mPeers
std::set< Peer::id_t > mPeers
The identifiers of the peers we are tracking.
Definition: PeerSet.h:120
std::chrono::milliseconds
std::function
ripple::PeerSet::addPeers
void addPeers(std::size_t limit, std::function< bool(std::shared_ptr< Peer > const &)> score)
Add at most limit peers to this set from the overlay.
Definition: PeerSet.cpp:50
ripple::PeerSet::mHash
const uint256 mHash
The hash of the object (in practice, always a ledger) we are trying to fetch.
Definition: PeerSet.h:112
std::sort
T sort(T... args)
ripple::PeerSet::sendRequest
void sendRequest(const protocol::TMGetLedger &message, std::shared_ptr< Peer > const &peer)
Send a GetLedger message to one or all peers.
Definition: PeerSet.cpp:127
ripple::base_uint< 256 >
ripple::PeerSet::~PeerSet
virtual ~PeerSet()=0
ripple::PeerSet::PeerSet
PeerSet(Application &app, uint256 const &hash, std::chrono::milliseconds interval, beast::Journal journal)
Definition: PeerSet.cpp:29
std::unique_lock< std::recursive_mutex >
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::ManifestDisposition::accepted
@ accepted
Manifest is valid.
std::vector::emplace_back
T emplace_back(T... args)
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:105
std::vector::begin
T begin(T... args)
ripple::Application::overlay
virtual Overlay & overlay()=0
ripple::PeerSet::onPeerAdded
virtual void onPeerAdded(std::shared_ptr< Peer > const &)=0
Hook called from addPeers().
ripple::PeerSet::mTimerInterval
std::chrono::milliseconds mTimerInterval
The minimum time to wait between calls to execute().
Definition: PeerSet.h:124
ripple::PeerSet::m_journal
beast::Journal m_journal
Definition: PeerSet.h:106
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
std::size_t
std::vector::end
T end(T... args)
ripple::PeerSet::mTimeouts
int mTimeouts
Definition: PeerSet.h:113
ripple::PeerSet::pmDowncast
virtual std::weak_ptr< PeerSet > pmDowncast()=0
Return a weak pointer to this.
ripple::PeerSet::setTimer
void setTimer()
Schedule a call to queueJob() after mTimerInterval.
Definition: PeerSet.cpp:87
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:108