diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj
index c2311041c..da7afca75 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj
+++ b/Builds/VisualStudio2012/RippleD.vcxproj
@@ -1654,6 +1654,7 @@
+
@@ -1686,6 +1687,7 @@
+
@@ -1739,7 +1741,6 @@
-
diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters
index e6671febf..fd977493e 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters
@@ -1104,9 +1104,6 @@
[1] Ripple\types\impl
-
- [2] Old Ripple\ripple_app\main
-
[1] Ripple\resource
@@ -2232,9 +2229,6 @@
[1] Ripple\peerfinder\impl
-
- [1] Ripple\types\api
-
[1] Ripple\peerfinder\impl
@@ -2250,9 +2244,6 @@
[1] Ripple\types\api
-
- [2] Old Ripple\ripple_app\main
-
[1] Ripple\resource
@@ -2307,6 +2298,12 @@
[1] Ripple\resource\impl
+
+ [1] Ripple\algorithm
+
+
+ [1] Ripple\peerfinder\impl
+
diff --git a/src/ripple/types/api/CycledSet.h b/src/ripple/algorithm/api/CycledSet.h
similarity index 97%
rename from src/ripple/types/api/CycledSet.h
rename to src/ripple/algorithm/api/CycledSet.h
index cfee79415..a89466171 100644
--- a/src/ripple/types/api/CycledSet.h
+++ b/src/ripple/algorithm/api/CycledSet.h
@@ -20,6 +20,9 @@
#ifndef RIPPLE_TYPES_CYCLEDSET_H_INCLUDED
#define RIPPLE_TYPES_CYCLEDSET_H_INCLUDED
+#include "beast/modules/beast_core/system/BeforeBoost.h"
+#include
+
namespace ripple {
/** Cycled set of unique keys.
diff --git a/src/ripple/peerfinder/api/Endpoint.h b/src/ripple/peerfinder/api/Endpoint.h
index ed7d6ef86..28a62d93e 100644
--- a/src/ripple/peerfinder/api/Endpoint.h
+++ b/src/ripple/peerfinder/api/Endpoint.h
@@ -32,7 +32,7 @@ struct Endpoint
int hops;
uint32 incomingSlotsAvailable;
uint32 incomingSlotsMax;
- uint32 uptimeMinutes;
+ uint32 uptimeSeconds;
std::string featureList;
};
diff --git a/src/ripple/peerfinder/impl/Cache.h b/src/ripple/peerfinder/impl/Cache.h
index e5f656408..8d1459907 100644
--- a/src/ripple/peerfinder/impl/Cache.h
+++ b/src/ripple/peerfinder/impl/Cache.h
@@ -90,11 +90,11 @@ public:
entry.message.hops = std::min (entry.message.hops, message.hops);
// Copy the other fields based on uptime
- if (entry.message.uptimeMinutes < message.uptimeMinutes)
+ if (entry.message.uptimeSeconds < message.uptimeSeconds)
{
entry.message.incomingSlotsAvailable = message.incomingSlotsAvailable;
entry.message.incomingSlotsMax = message.incomingSlotsMax;
- entry.message.uptimeMinutes = message.uptimeMinutes;
+ entry.message.uptimeSeconds = message.uptimeSeconds;
entry.message.featureList = message.featureList;
}
diff --git a/src/ripple/peerfinder/impl/Endpoint.cpp b/src/ripple/peerfinder/impl/Endpoint.cpp
index 25ad77c62..d9956abf9 100644
--- a/src/ripple/peerfinder/impl/Endpoint.cpp
+++ b/src/ripple/peerfinder/impl/Endpoint.cpp
@@ -26,7 +26,7 @@ Endpoint::Endpoint ()
: hops (0)
, incomingSlotsAvailable (0)
, incomingSlotsMax (0)
- , uptimeMinutes (0)
+ , uptimeSeconds (0)
{
}
diff --git a/src/ripple/peerfinder/impl/Logic.h b/src/ripple/peerfinder/impl/Logic.h
index 9a505b0aa..a4dc574c9 100644
--- a/src/ripple/peerfinder/impl/Logic.h
+++ b/src/ripple/peerfinder/impl/Logic.h
@@ -77,10 +77,12 @@ public:
//--------------------------------------------------------------------------
+ DiscreteClock m_clock;
Callback& m_callback;
Store& m_store;
Checker& m_checker;
Journal m_journal;
+
Config m_config;
// The number of fixed peers that are currently connected
@@ -106,20 +108,28 @@ public:
//--------------------------------------------------------------------------
Logic (
+ DiscreteClock clock,
Callback& callback,
Store& store,
Checker& checker,
Journal journal)
- : m_callback (callback)
+ : m_clock (clock)
+ , m_callback (callback)
, m_store (store)
, m_checker (checker)
, m_journal (journal)
, m_fixedPeersConnected (0)
+ , m_slots (clock)
, m_cache (journal)
, m_legacyCache (store, journal)
{
}
+ DiscreteTime get_now()
+ {
+ return m_clock();
+ }
+
/** Stop the logic.
This will cancel the current fetch and set the stopping flag
to `true` to prevent further fetches.
@@ -156,7 +166,7 @@ public:
ep.hops = 0;
ep.incomingSlotsAvailable = m_slots.inboundSlots;
ep.incomingSlotsMax = m_slots.inboundSlotsMaximum;
- ep.uptimeMinutes = m_slots.uptimeMinutes();
+ ep.uptimeSeconds = m_slots.uptimeSeconds();
return ep;
}
@@ -208,14 +218,6 @@ public:
m_callback.connectPeerEndpoints (list);
}
- // Returns the number of seconds that have elapsed since some baseline
- // event.
- //
- virtual DiscreteTime get_now()
- {
- return 0;
- }
-
//--------------------------------------------------------------------------
//
// Logic
@@ -259,7 +261,7 @@ public:
//
void cycleCache()
{
- m_cache.cycle(get_now());
+ m_cache.cycle (get_now());
for (Peers::iterator iter (m_peers.begin());
iter != m_peers.end(); ++iter)
diff --git a/src/ripple/peerfinder/impl/LogicType.h b/src/ripple/peerfinder/impl/LogicType.h
index de90b23a1..c99f24976 100644
--- a/src/ripple/peerfinder/impl/LogicType.h
+++ b/src/ripple/peerfinder/impl/LogicType.h
@@ -23,28 +23,32 @@
namespace ripple {
namespace PeerFinder {
-/** Provides the Clock required by Logic's get_now().
- This allows the unit tests to provide its own manual clock.
-*/
-template
-class LogicType : public Logic
+template
+class LogicType
+ : private BaseFromMember
+ , public Logic
{
public:
- explicit LogicType (Callback& callback,
- Store& store,
- Checker& checker,
- Journal journal)
- : Logic (callback, store, checker, journal)
+ typedef typename DiscreteClockSourceType::DiscreteClockType DiscreteClockType;
+
+ LogicType (
+ Callback& callback,
+ Store& store,
+ Checker& checker,
+ Journal journal)
+ : Logic (
+ BaseFromMember ::member(),
+ callback,
+ store,
+ checker,
+ journal)
{
}
- DiscreteTime get_now ()
+ DiscreteClockSourceType& get_clock()
{
- return m_clock();
+ return BaseFromMember ::member();
}
-
-private:
- Clock m_clock;
};
}
diff --git a/src/ripple/peerfinder/impl/Manager.cpp b/src/ripple/peerfinder/impl/Manager.cpp
index 86a1f3120..114145563 100644
--- a/src/ripple/peerfinder/impl/Manager.cpp
+++ b/src/ripple/peerfinder/impl/Manager.cpp
@@ -340,7 +340,7 @@ public:
map ["out_desired"] = m_logic.m_slots.outDesired;
map ["in_avail"] = m_logic.m_slots.inboundSlots;
map ["in_max"] = m_logic.m_slots.inboundSlotsMaximum;
- map ["minutes"] = m_logic.m_slots.uptimeMinutes();
+ map ["uptime"] = m_logic.m_slots.uptimeSeconds();
map ["round"] = m_logic.m_slots.roundUpwards();
map ["cache"] = uint32(m_logic.m_cache.size());
map ["legacy"] = uint32(m_logic.m_legacyCache.size());
diff --git a/src/ripple/peerfinder/impl/SimpleMonotonicClock.h b/src/ripple/peerfinder/impl/SimpleMonotonicClock.h
deleted file mode 100644
index c178ac1b5..000000000
--- a/src/ripple/peerfinder/impl/SimpleMonotonicClock.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of rippled: https://github.com/ripple/rippled
- Copyright (c) 2012, 2013 Ripple Labs Inc.
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-//==============================================================================
-
-#ifndef RIPPLE_PEERFINDER_SIMPLEMONOTONICCLOCK_H_INCLUDED
-#define RIPPLE_PEERFINDER_SIMPLEMONOTONICCLOCK_H_INCLUDED
-
-namespace ripple {
-namespace PeerFinder {
-
-/** Monotonically increasing time value. */
-struct SimpleMonotonicClock
-{
- typedef int value_type;
-
- value_type operator() () const
- {
- return value_type (RelativeTime::fromStartup().inSeconds());
- }
-};
-
-}
-}
-
-#endif
diff --git a/src/ripple/peerfinder/impl/Slots.cpp b/src/ripple/peerfinder/impl/Slots.cpp
index 8f111bc76..6f9eb6827 100644
--- a/src/ripple/peerfinder/impl/Slots.cpp
+++ b/src/ripple/peerfinder/impl/Slots.cpp
@@ -20,15 +20,17 @@
namespace ripple {
namespace PeerFinder {
-Slots::Slots ()
- : startTime (0)
+Slots::Slots (DiscreteClock clock, bool roundUpwards)
+ : m_clock (clock)
+ , m_startTime (0)
, peerCount (0)
, inboundCount (0)
, outboundCount (0)
+ , fixedCount (0)
, outDesired (0)
, inboundSlots (0)
, inboundSlotsMaximum (0)
- , m_roundUpwards (Random::getSystemRandom().nextBool())
+ , m_roundUpwards (roundUpwards)
{
}
@@ -58,7 +60,7 @@ void Slots::update (Config const& config)
void Slots::addPeer (Config const& config, bool inbound)
{
if (peerCount == 0)
- startTime = RelativeTime::fromStartup();
+ m_startTime = m_clock();
++peerCount;
if (inbound)
@@ -71,24 +73,51 @@ void Slots::addPeer (Config const& config, bool inbound)
void Slots::dropPeer (Config const& config, bool inbound)
{
+ bool const wasConnected (connected ());
+
--peerCount;
if (inbound)
--inboundCount;
else
--outboundCount;
- if (peerCount == 0)
- startTime = RelativeTime(0);
+ if (wasConnected && ! connected())
+ m_startTime = 0;
update (config);
}
-uint32 Slots::uptimeMinutes () const
+bool Slots::roundUpwards () const
{
- if (startTime.isNotZero())
- return (RelativeTime::fromStartup()-startTime).inMinutes();
+ return m_roundUpwards;
+}
+
+bool Slots::connected () const
+{
+ return (peerCount-fixedCount) >= Config::minOutCount;
+}
+
+uint32 Slots::uptimeSeconds () const
+{
+ if (m_startTime != 0)
+ return m_clock() - m_startTime;
return 0;
}
+void Slots::updateConnected ()
+{
+ bool const wasConnected (m_startTime != 0);
+ bool const isConnected (connected());
+
+ if (wasConnected && !isConnected)
+ {
+ m_startTime = 0;
+ }
+ else if (! wasConnected && isConnected)
+ {
+ m_startTime = m_clock();
+ }
+}
+
}
}
diff --git a/src/ripple/peerfinder/impl/Slots.h b/src/ripple/peerfinder/impl/Slots.h
index f3b1ee14e..8fc156da2 100644
--- a/src/ripple/peerfinder/impl/Slots.h
+++ b/src/ripple/peerfinder/impl/Slots.h
@@ -26,15 +26,14 @@ namespace PeerFinder {
class Slots
{
public:
- Slots ();
+ explicit Slots (
+ DiscreteClock clock,
+ bool roundUpwards = Random::getSystemRandom().nextBool());
void update (Config const& config);
void addPeer (Config const& config, bool inbound);
void dropPeer (Config const& config, bool inbound);
- // Most recent time when we went from 0 to 1 peers
- RelativeTime startTime;
-
// Current total of connected peers that have HELLOed
int peerCount;
@@ -44,6 +43,10 @@ public:
// The portion of peers which are outgoing connections
int outboundCount;
+ // The portion of peers which are the fixed peers.
+ // Fixed peers don't count towards connection limits.
+ int fixedCount;
+
// The number of outgoing peer connections we want (calculated)
int outDesired;
@@ -53,17 +56,25 @@ public:
// The maximum number of incoming slots (calculated)
int inboundSlotsMaximum;
- // Returns the uptime in minutes
+ // Returns `true` if we round fractional slot availability upwards
+ bool roundUpwards () const;
+
+ // Returns `true` if we meet the criteria of
+ // "connected to the network based on the current values of slots.
+ //
+ bool connected () const;
+
+ // Returns the uptime in seconds
// Uptime is measured from the last we transitioned from not
// being connected to the network, to being connected.
//
- uint32 uptimeMinutes () const;
-
- // Returns `true` if we round fractional slot availability upwards
- bool roundUpwards () const
- { return m_roundUpwards; }
+ uint32 uptimeSeconds () const;
private:
+ void updateConnected();
+
+ DiscreteTime m_startTime;
+ DiscreteClock m_clock;
bool m_roundUpwards;
};
diff --git a/src/ripple/peerfinder/impl/Tests.cpp b/src/ripple/peerfinder/impl/Tests.cpp
index 836d02bbc..664232a62 100644
--- a/src/ripple/peerfinder/impl/Tests.cpp
+++ b/src/ripple/peerfinder/impl/Tests.cpp
@@ -23,9 +23,78 @@ namespace PeerFinder {
class PeerFinderTests : public UnitTest
{
public:
+ // Complete Logic used for tests
+ //
+ class TestLogic
+ : public LogicType
+ , public Callback
+ , public Store
+ , public Checker
+ {
+ public:
+ Journal m_journal;
+
+ explicit TestLogic (Journal journal)
+ : LogicType (*this, *this, *this, journal)
+ , m_journal (journal)
+ {
+ }
+
+ //
+ // Callback
+ //
+
+ void sendPeerEndpoints (PeerID const& id,
+ std::vector const& endpoints)
+ {
+ }
+
+ void connectPeerEndpoints (std::vector const& list)
+ {
+ }
+
+ void chargePeerLoadPenalty (PeerID const& id)
+ {
+ }
+
+ //
+ // Store
+ //
+
+ void loadLegacyEndpoints (std::vector & list)
+ {
+ }
+
+ void updateLegacyEndpoints (std::vector const& list)
+ {
+ }
+
+ //
+ // Checker
+ //
+
+ void cancel ()
+ {
+ }
+
+ void async_test (IPAddress const& address,
+ AbstractHandler handler)
+ {
+ Checker::Result result;
+ result.address = address;
+ result.canAccept = false;
+ handler (result);
+ }
+ };
+
+ //--------------------------------------------------------------------------
+
void runTest ()
{
beginTestCase ("logic");
+
+ TestLogic logic (journal());
+
pass ();
}
diff --git a/src/ripple/peerfinder/ripple_peerfinder.cpp b/src/ripple/peerfinder/ripple_peerfinder.cpp
index 51b18d5e1..299a38863 100644
--- a/src/ripple/peerfinder/ripple_peerfinder.cpp
+++ b/src/ripple/peerfinder/ripple_peerfinder.cpp
@@ -21,7 +21,8 @@
#include "ripple_peerfinder.h"
-#include "../../ripple/types/ripple_types.h"
+#include "../../ripple/algorithm/api/CycledSet.h"
+#include "../../ripple/algorithm/api/DiscreteClock.h"
#include
@@ -42,7 +43,6 @@ namespace ripple {
using namespace beast;
}
-#include "impl/SimpleMonotonicClock.h"
#include "impl/PrivateTypes.h"
# include "impl/Tuning.h"
# include "impl/Checker.h"
@@ -57,8 +57,8 @@ using namespace beast;
# include "impl/LegacyEndpointCache.h"
# include "impl/PeerInfo.h"
#include "impl/StoreSqdb.h"
+# include "impl/LogicType.h"
#include "impl/Logic.h"
-#include "impl/LogicType.h"
#include "impl/Checker.cpp"
#include "impl/Config.cpp"
diff --git a/src/ripple/types/ripple_types.h b/src/ripple/types/ripple_types.h
index d5b20f506..ee03dc640 100644
--- a/src/ripple/types/ripple_types.h
+++ b/src/ripple/types/ripple_types.h
@@ -45,7 +45,6 @@ using namespace beast;
}
#include "api/AgedHistory.h"
-#include "api/CycledSet.h"
# include "api/Blob.h"
# include "api/Base58.h"
# include "api/ByteOrder.h"
diff --git a/src/ripple/validators/ripple_validators.cpp b/src/ripple/validators/ripple_validators.cpp
index d9f49799f..1bbfccad7 100644
--- a/src/ripple/validators/ripple_validators.cpp
+++ b/src/ripple/validators/ripple_validators.cpp
@@ -35,6 +35,7 @@
#include "beast/modules/beast_asio/beast_asio.h"
#include "beast/modules/beast_sqdb/beast_sqdb.h"
+#include "../algorithm/api/CycledSet.h"
#include "../testoverlay/ripple_testoverlay.h" // for unit test
namespace ripple {
diff --git a/src/ripple_app/peers/Peer.cpp b/src/ripple_app/peers/Peer.cpp
index 8e5de9466..69af60068 100644
--- a/src/ripple_app/peers/Peer.cpp
+++ b/src/ripple_app/peers/Peer.cpp
@@ -1752,8 +1752,8 @@ void PeerImp::recvEndpoints (protocol::TMEndpoints& packet)
// maxSlots
endpoint.incomingSlotsMax = tm.maxslots();
- // uptimeMinutes
- endpoint.uptimeMinutes = tm.uptimeminutes();
+ // uptimeSeconds
+ endpoint.uptimeSeconds = tm.uptimeseconds();
endpoints.push_back (endpoint);
}
diff --git a/src/ripple_app/peers/Peers.cpp b/src/ripple_app/peers/Peers.cpp
index 27ecfa098..a4f4020ea 100644
--- a/src/ripple_app/peers/Peers.cpp
+++ b/src/ripple_app/peers/Peers.cpp
@@ -169,7 +169,7 @@ public:
tme.set_hops (ep.hops);
tme.set_slots (ep.incomingSlotsAvailable);
tme.set_maxslots (ep.incomingSlotsMax);
- tme.set_uptimeminutes (ep.uptimeMinutes);
+ tme.set_uptimeseconds (ep.uptimeSeconds);
tme.set_features (ep.featureList);
}
diff --git a/src/ripple_data/protocol/ripple.proto b/src/ripple_data/protocol/ripple.proto
index 1443d7876..92e86669a 100644
--- a/src/ripple_data/protocol/ripple.proto
+++ b/src/ripple_data/protocol/ripple.proto
@@ -239,7 +239,7 @@ message TMEndpoint
required uint32 hops = 2;
required uint32 slots = 3; // the number of available incoming slots
required uint32 maxSlots = 4; // the maximum number of incoming slots
- required uint32 uptimeMinutes = 5; // uptime in minutes
+ required uint32 uptimeSeconds = 5; // uptime in seconds
required string features = 6;
}