|
|
|
|
@@ -76,14 +76,15 @@ namespace ripple {
|
|
|
|
|
#define REFERRAL_IPS_MAX 50
|
|
|
|
|
|
|
|
|
|
template<class Iterator>
|
|
|
|
|
static
|
|
|
|
|
std::string
|
|
|
|
|
strJoin (Iterator first, Iterator last, std::string strSeperator)
|
|
|
|
|
strJoin (Iterator first, Iterator last, std::string strSeparator)
|
|
|
|
|
{
|
|
|
|
|
std::ostringstream ossValues;
|
|
|
|
|
|
|
|
|
|
for (Iterator start = first; first != last; first++)
|
|
|
|
|
for (Iterator start = first; first != last; ++first)
|
|
|
|
|
{
|
|
|
|
|
ossValues << str (boost::format ("%s%s") % (start == first ? "" : strSeperator) % *first);
|
|
|
|
|
ossValues << str (boost::format ("%s%s") % (start == first ? "" : strSeparator) % *first);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ossValues.str ();
|
|
|
|
|
@@ -196,8 +197,203 @@ private:
|
|
|
|
|
std::vector<int> viReferrals;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
typedef RippleMutex FetchLockType;
|
|
|
|
|
typedef std::lock_guard <FetchLockType> ScopedFetchLockType;
|
|
|
|
|
FetchLockType mFetchLock;
|
|
|
|
|
|
|
|
|
|
typedef RippleRecursiveMutex UNLLockType;
|
|
|
|
|
typedef std::lock_guard <UNLLockType> ScopedUNLLockType;
|
|
|
|
|
UNLLockType mUNLLock;
|
|
|
|
|
|
|
|
|
|
// VFALCO TODO Replace ptime with beast::Time
|
|
|
|
|
// Misc persistent information
|
|
|
|
|
boost::posix_time::ptime mtpScoreUpdated;
|
|
|
|
|
boost::posix_time::ptime mtpFetchUpdated;
|
|
|
|
|
|
|
|
|
|
// XXX Make this faster, make this the contents vector unsigned char or raw public key.
|
|
|
|
|
// XXX Contents needs to based on score.
|
|
|
|
|
hash_set<std::string> mUNL;
|
|
|
|
|
|
|
|
|
|
boost::posix_time::ptime mtpScoreNext; // When to start scoring.
|
|
|
|
|
boost::posix_time::ptime mtpScoreStart; // Time currently started scoring.
|
|
|
|
|
beast::DeadlineTimer m_scoreTimer; // Timer to start scoring.
|
|
|
|
|
|
|
|
|
|
int mFetchActive; // Count of active fetches.
|
|
|
|
|
|
|
|
|
|
boost::posix_time::ptime mtpFetchNext; // Time of to start next fetch.
|
|
|
|
|
beast::DeadlineTimer m_fetchTimer; // Timer to start fetching.
|
|
|
|
|
|
|
|
|
|
std::map<RippleAddress, ClusterNodeStatus> m_clusterNodes;
|
|
|
|
|
|
|
|
|
|
std::string node_file_name_;
|
|
|
|
|
std::string node_file_path_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit UniqueNodeListImp (Stoppable& parent)
|
|
|
|
|
explicit UniqueNodeListImp (Stoppable& parent);
|
|
|
|
|
|
|
|
|
|
void onStop();
|
|
|
|
|
|
|
|
|
|
void doScore();
|
|
|
|
|
|
|
|
|
|
void doFetch();
|
|
|
|
|
|
|
|
|
|
void onDeadlineTimer (beast::DeadlineTimer& timer);
|
|
|
|
|
|
|
|
|
|
// This is called when the application is started.
|
|
|
|
|
// Get update times and start fetching and scoring as needed.
|
|
|
|
|
void start();
|
|
|
|
|
|
|
|
|
|
// Add a trusted node. Called by RPC or other source.
|
|
|
|
|
void nodeAddPublic (RippleAddress const& naNodePublic, ValidatorSource vsWhy, std::string const& strComment);
|
|
|
|
|
|
|
|
|
|
// Queue a domain for a single attempt fetch a ripple.txt.
|
|
|
|
|
// --> strComment: only used on vsManual
|
|
|
|
|
// YYY As a lot of these may happen at once, would be nice to wrap multiple calls in a transaction.
|
|
|
|
|
void nodeAddDomain (std::string strDomain, ValidatorSource vsWhy, std::string const& strComment);
|
|
|
|
|
|
|
|
|
|
void nodeRemovePublic (RippleAddress const& naNodePublic);
|
|
|
|
|
|
|
|
|
|
void nodeRemoveDomain (std::string strDomain);
|
|
|
|
|
|
|
|
|
|
void nodeReset();
|
|
|
|
|
|
|
|
|
|
// For debugging, schedule forced scoring.
|
|
|
|
|
void nodeScore();
|
|
|
|
|
|
|
|
|
|
bool nodeInUNL (RippleAddress const& naNodePublic);
|
|
|
|
|
|
|
|
|
|
bool nodeInCluster (RippleAddress const& naNodePublic);
|
|
|
|
|
bool nodeInCluster (RippleAddress const& naNodePublic, std::string& name);
|
|
|
|
|
|
|
|
|
|
bool nodeUpdate (RippleAddress const& naNodePublic, ClusterNodeStatus const& cnsStatus);
|
|
|
|
|
|
|
|
|
|
std::map<RippleAddress, ClusterNodeStatus> getClusterStatus();
|
|
|
|
|
|
|
|
|
|
std::uint32_t getClusterFee();
|
|
|
|
|
|
|
|
|
|
void addClusterStatus (Json::Value& obj);
|
|
|
|
|
|
|
|
|
|
void nodeBootstrap();
|
|
|
|
|
|
|
|
|
|
bool nodeLoad (boost::filesystem::path pConfig);
|
|
|
|
|
|
|
|
|
|
void nodeNetwork();
|
|
|
|
|
|
|
|
|
|
Json::Value getUnlJson();
|
|
|
|
|
|
|
|
|
|
// For each kind of source, have a starting number of points to be distributed.
|
|
|
|
|
int iSourceScore (ValidatorSource vsWhy);
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
private:
|
|
|
|
|
// Load information about when we last updated.
|
|
|
|
|
bool miscLoad();
|
|
|
|
|
|
|
|
|
|
// Persist update information.
|
|
|
|
|
bool miscSave();
|
|
|
|
|
|
|
|
|
|
void trustedLoad();
|
|
|
|
|
|
|
|
|
|
// For a round of scoring we destribute points from a node to nodes it refers to.
|
|
|
|
|
// Returns true, iff scores were distributed.
|
|
|
|
|
//
|
|
|
|
|
bool scoreRound (std::vector<scoreNode>& vsnNodes);
|
|
|
|
|
|
|
|
|
|
// From SeedDomains and ValidatorReferrals compute scores and update TrustedNodes.
|
|
|
|
|
//
|
|
|
|
|
// VFALCO TODO Shrink this function, break it up
|
|
|
|
|
//
|
|
|
|
|
void scoreCompute();
|
|
|
|
|
|
|
|
|
|
// Start a timer to update scores.
|
|
|
|
|
// <-- bNow: true, to force scoring for debugging.
|
|
|
|
|
void scoreNext (bool bNow);
|
|
|
|
|
|
|
|
|
|
// Given a ripple.txt, process it.
|
|
|
|
|
//
|
|
|
|
|
// VFALCO TODO Can't we take a filename or stream instead of a string?
|
|
|
|
|
//
|
|
|
|
|
bool responseFetch (std::string const& strDomain, const boost::system::error_code& err, int iStatus, std::string const& strSiteFile);
|
|
|
|
|
|
|
|
|
|
// Try to process the next fetch of a ripple.txt.
|
|
|
|
|
void fetchNext();
|
|
|
|
|
|
|
|
|
|
// Called when we need to update scores.
|
|
|
|
|
void fetchDirty();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void fetchFinish();
|
|
|
|
|
|
|
|
|
|
// Get the ripple.txt and process it.
|
|
|
|
|
void fetchProcess (std::string strDomain);
|
|
|
|
|
|
|
|
|
|
// Process IniFileSections [validators_url].
|
|
|
|
|
void getValidatorsUrl (RippleAddress const& naNodePublic,
|
|
|
|
|
IniFileSections secSite);
|
|
|
|
|
|
|
|
|
|
// Process IniFileSections [ips_url].
|
|
|
|
|
// If we have a IniFileSections with a single entry, fetch the url and process it.
|
|
|
|
|
void getIpsUrl (RippleAddress const& naNodePublic, IniFileSections secSite);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Given a IniFileSections with IPs, parse and persist it for a validator.
|
|
|
|
|
bool responseIps (std::string const& strSite, RippleAddress const& naNodePublic, const boost::system::error_code& err, int iStatus, std::string const& strIpsFile);;
|
|
|
|
|
|
|
|
|
|
// After fetching a ripple.txt from a web site, given a IniFileSections with validators, parse and persist it.
|
|
|
|
|
bool responseValidators (std::string const& strValidatorsUrl, RippleAddress const& naNodePublic, IniFileSections secSite, std::string const& strSite, const boost::system::error_code& err, int iStatus, std::string const& strValidatorsFile);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Persist the IPs refered to by a Validator.
|
|
|
|
|
// --> strSite: source of the IPs (for debugging)
|
|
|
|
|
// --> naNodePublic: public key of the validating node.
|
|
|
|
|
void processIps (std::string const& strSite, RippleAddress const& naNodePublic, IniFileSections::mapped_type* pmtVecStrIps);
|
|
|
|
|
|
|
|
|
|
// Persist ValidatorReferrals.
|
|
|
|
|
// --> strSite: source site for display
|
|
|
|
|
// --> strValidatorsSrc: source details for display
|
|
|
|
|
// --> naNodePublic: remote source public key - not valid for local
|
|
|
|
|
// --> vsWhy: reason for adding validator to SeedDomains or SeedNodes.
|
|
|
|
|
int processValidators (std::string const& strSite, std::string const& strValidatorsSrc, RippleAddress const& naNodePublic, ValidatorSource vsWhy, IniFileSections::mapped_type* pmtVecStrValidators);
|
|
|
|
|
|
|
|
|
|
// Process a ripple.txt.
|
|
|
|
|
void processFile (std::string const& strDomain, RippleAddress const& naNodePublic, IniFileSections secSite);
|
|
|
|
|
|
|
|
|
|
// Retrieve a SeedDomain from DB.
|
|
|
|
|
bool getSeedDomains (std::string const& strDomain, seedDomain& dstSeedDomain);
|
|
|
|
|
|
|
|
|
|
// Persist a SeedDomain.
|
|
|
|
|
void setSeedDomains (const seedDomain& sdSource, bool bNext);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Retrieve a SeedNode from DB.
|
|
|
|
|
bool getSeedNodes (RippleAddress const& naNodePublic, seedNode& dstSeedNode);
|
|
|
|
|
|
|
|
|
|
// Persist a SeedNode.
|
|
|
|
|
// <-- bNext: true, to do fetching if needed.
|
|
|
|
|
void setSeedNodes (const seedNode& snSource, bool bNext);
|
|
|
|
|
|
|
|
|
|
bool validatorsResponse (const boost::system::error_code& err, int iStatus, std::string strResponse);
|
|
|
|
|
|
|
|
|
|
// Process a validators.txt.
|
|
|
|
|
// --> strSite: source of validators
|
|
|
|
|
// --> strValidators: contents of a validators.txt
|
|
|
|
|
//
|
|
|
|
|
// VFALCO TODO Can't we name this processValidatorList?
|
|
|
|
|
//
|
|
|
|
|
void nodeProcess (std::string const& strSite, std::string const& strValidators, std::string const& strSource);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
UniqueNodeList::UniqueNodeList (Stoppable& parent)
|
|
|
|
|
: Stoppable ("UniqueNodeList", parent)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
UniqueNodeListImp::UniqueNodeListImp (Stoppable& parent)
|
|
|
|
|
: UniqueNodeList (parent)
|
|
|
|
|
, m_scoreTimer (this)
|
|
|
|
|
, mFetchActive (0)
|
|
|
|
|
@@ -207,9 +403,7 @@ public:
|
|
|
|
|
node_file_path_ = "/" + node_file_name_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void onStop ()
|
|
|
|
|
void UniqueNodeListImp::onStop()
|
|
|
|
|
{
|
|
|
|
|
m_fetchTimer.cancel ();
|
|
|
|
|
m_scoreTimer.cancel ();
|
|
|
|
|
@@ -217,9 +411,7 @@ public:
|
|
|
|
|
stopped ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void doScore ()
|
|
|
|
|
void UniqueNodeListImp::doScore()
|
|
|
|
|
{
|
|
|
|
|
mtpScoreNext = boost::posix_time::ptime (boost::posix_time::not_a_date_time); // Timer not set.
|
|
|
|
|
mtpScoreStart = boost::posix_time::second_clock::universal_time (); // Scoring.
|
|
|
|
|
@@ -240,14 +432,14 @@ public:
|
|
|
|
|
scoreNext (false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void doFetch ()
|
|
|
|
|
void UniqueNodeListImp::doFetch()
|
|
|
|
|
{
|
|
|
|
|
// Time to check for another fetch.
|
|
|
|
|
WriteLog (lsTRACE, UniqueNodeList) << "fetchTimerHandler";
|
|
|
|
|
fetchNext ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void onDeadlineTimer (beast::DeadlineTimer& timer)
|
|
|
|
|
void UniqueNodeListImp::onDeadlineTimer (beast::DeadlineTimer& timer)
|
|
|
|
|
{
|
|
|
|
|
if (timer == m_scoreTimer)
|
|
|
|
|
{
|
|
|
|
|
@@ -261,11 +453,9 @@ public:
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// This is called when the application is started.
|
|
|
|
|
// Get update times and start fetching and scoring as needed.
|
|
|
|
|
void start ()
|
|
|
|
|
void UniqueNodeListImp::start()
|
|
|
|
|
{
|
|
|
|
|
miscLoad ();
|
|
|
|
|
|
|
|
|
|
@@ -279,7 +469,7 @@ public:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Add a trusted node. Called by RPC or other source.
|
|
|
|
|
void nodeAddPublic (RippleAddress const& naNodePublic, ValidatorSource vsWhy, std::string const& strComment)
|
|
|
|
|
void UniqueNodeListImp::nodeAddPublic (RippleAddress const& naNodePublic, ValidatorSource vsWhy, std::string const& strComment)
|
|
|
|
|
{
|
|
|
|
|
seedNode snCurrent;
|
|
|
|
|
|
|
|
|
|
@@ -316,7 +506,7 @@ public:
|
|
|
|
|
// Queue a domain for a single attempt fetch a ripple.txt.
|
|
|
|
|
// --> strComment: only used on vsManual
|
|
|
|
|
// YYY As a lot of these may happen at once, would be nice to wrap multiple calls in a transaction.
|
|
|
|
|
void nodeAddDomain (std::string strDomain, ValidatorSource vsWhy, std::string const& strComment)
|
|
|
|
|
void UniqueNodeListImp::nodeAddDomain (std::string strDomain, ValidatorSource vsWhy, std::string const& strComment)
|
|
|
|
|
{
|
|
|
|
|
boost::trim (strDomain);
|
|
|
|
|
boost::to_lower (strDomain);
|
|
|
|
|
@@ -359,7 +549,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void nodeRemovePublic (RippleAddress const& naNodePublic)
|
|
|
|
|
void UniqueNodeListImp::nodeRemovePublic (RippleAddress const& naNodePublic)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
auto db = getApp().getWalletDB ().checkoutDb ();
|
|
|
|
|
@@ -381,7 +571,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void nodeRemoveDomain (std::string strDomain)
|
|
|
|
|
void UniqueNodeListImp::nodeRemoveDomain (std::string strDomain)
|
|
|
|
|
{
|
|
|
|
|
boost::trim (strDomain);
|
|
|
|
|
boost::to_lower (strDomain);
|
|
|
|
|
@@ -398,7 +588,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void nodeReset ()
|
|
|
|
|
void UniqueNodeListImp::nodeReset()
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
auto db = getApp().getWalletDB ().checkoutDb ();
|
|
|
|
|
@@ -413,14 +603,14 @@ public:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// For debugging, schedule forced scoring.
|
|
|
|
|
void nodeScore ()
|
|
|
|
|
void UniqueNodeListImp::nodeScore()
|
|
|
|
|
{
|
|
|
|
|
scoreNext (true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
bool nodeInUNL (RippleAddress const& naNodePublic)
|
|
|
|
|
bool UniqueNodeListImp::nodeInUNL (RippleAddress const& naNodePublic)
|
|
|
|
|
{
|
|
|
|
|
ScopedUNLLockType sl (mUNLLock);
|
|
|
|
|
|
|
|
|
|
@@ -429,7 +619,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
bool nodeInCluster (RippleAddress const& naNodePublic)
|
|
|
|
|
bool UniqueNodeListImp::nodeInCluster (RippleAddress const& naNodePublic)
|
|
|
|
|
{
|
|
|
|
|
ScopedUNLLockType sl (mUNLLock);
|
|
|
|
|
return m_clusterNodes.end () != m_clusterNodes.find (naNodePublic);
|
|
|
|
|
@@ -437,7 +627,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
bool nodeInCluster (RippleAddress const& naNodePublic, std::string& name)
|
|
|
|
|
bool UniqueNodeListImp::nodeInCluster (RippleAddress const& naNodePublic, std::string& name)
|
|
|
|
|
{
|
|
|
|
|
ScopedUNLLockType sl (mUNLLock);
|
|
|
|
|
std::map<RippleAddress, ClusterNodeStatus>::iterator it = m_clusterNodes.find (naNodePublic);
|
|
|
|
|
@@ -451,7 +641,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
bool nodeUpdate (RippleAddress const& naNodePublic, ClusterNodeStatus const& cnsStatus)
|
|
|
|
|
bool UniqueNodeListImp::nodeUpdate (RippleAddress const& naNodePublic, ClusterNodeStatus const& cnsStatus)
|
|
|
|
|
{
|
|
|
|
|
ScopedUNLLockType sl (mUNLLock);
|
|
|
|
|
return m_clusterNodes[naNodePublic].update(cnsStatus);
|
|
|
|
|
@@ -459,7 +649,8 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
std::map<RippleAddress, ClusterNodeStatus> getClusterStatus ()
|
|
|
|
|
std::map<RippleAddress, ClusterNodeStatus>
|
|
|
|
|
UniqueNodeListImp::getClusterStatus()
|
|
|
|
|
{
|
|
|
|
|
std::map<RippleAddress, ClusterNodeStatus> ret;
|
|
|
|
|
{
|
|
|
|
|
@@ -471,7 +662,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
std::uint32_t getClusterFee ()
|
|
|
|
|
std::uint32_t UniqueNodeListImp::getClusterFee()
|
|
|
|
|
{
|
|
|
|
|
int thresh = getApp().getOPs().getNetworkTimeNC() - 90;
|
|
|
|
|
|
|
|
|
|
@@ -496,7 +687,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void addClusterStatus (Json::Value& obj)
|
|
|
|
|
void UniqueNodeListImp::addClusterStatus (Json::Value& obj)
|
|
|
|
|
{
|
|
|
|
|
ScopedUNLLockType sl (mUNLLock);
|
|
|
|
|
if (m_clusterNodes.size() > 1) // nodes other than us
|
|
|
|
|
@@ -527,7 +718,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void nodeBootstrap ()
|
|
|
|
|
void UniqueNodeListImp::nodeBootstrap()
|
|
|
|
|
{
|
|
|
|
|
int iDomains = 0;
|
|
|
|
|
int iNodes = 0;
|
|
|
|
|
@@ -591,7 +782,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
bool nodeLoad (boost::filesystem::path pConfig)
|
|
|
|
|
bool UniqueNodeListImp::nodeLoad (boost::filesystem::path pConfig)
|
|
|
|
|
{
|
|
|
|
|
if (pConfig.empty ())
|
|
|
|
|
{
|
|
|
|
|
@@ -649,7 +840,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void nodeNetwork ()
|
|
|
|
|
void UniqueNodeListImp::nodeNetwork()
|
|
|
|
|
{
|
|
|
|
|
if (!getConfig ().VALIDATORS_SITE.empty ())
|
|
|
|
|
{
|
|
|
|
|
@@ -670,7 +861,7 @@ public:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
Json::Value getUnlJson ()
|
|
|
|
|
Json::Value UniqueNodeListImp::getUnlJson()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
Json::Value ret (Json::arrayValue);
|
|
|
|
|
@@ -698,7 +889,7 @@ public:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// For each kind of source, have a starting number of points to be distributed.
|
|
|
|
|
int iSourceScore (ValidatorSource vsWhy)
|
|
|
|
|
int UniqueNodeListImp::iSourceScore (ValidatorSource vsWhy)
|
|
|
|
|
{
|
|
|
|
|
int iScore = 0;
|
|
|
|
|
|
|
|
|
|
@@ -739,10 +930,8 @@ public:
|
|
|
|
|
return iScore;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
private:
|
|
|
|
|
// Load information about when we last updated.
|
|
|
|
|
bool miscLoad ()
|
|
|
|
|
bool UniqueNodeListImp::miscLoad()
|
|
|
|
|
{
|
|
|
|
|
auto db = getApp().getWalletDB ().checkoutDb ();
|
|
|
|
|
|
|
|
|
|
@@ -762,10 +951,8 @@ private:
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Persist update information.
|
|
|
|
|
bool miscSave ()
|
|
|
|
|
bool UniqueNodeListImp::miscSave()
|
|
|
|
|
{
|
|
|
|
|
auto db = getApp().getWalletDB ().checkoutDb ();
|
|
|
|
|
|
|
|
|
|
@@ -778,7 +965,7 @@ private:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void trustedLoad ()
|
|
|
|
|
void UniqueNodeListImp::trustedLoad()
|
|
|
|
|
{
|
|
|
|
|
boost::regex rNode ("\\`\\s*(\\S+)[\\s]*(.*)\\'");
|
|
|
|
|
for (auto const& c : getConfig ().CLUSTER_NODES)
|
|
|
|
|
@@ -816,7 +1003,7 @@ private:
|
|
|
|
|
// For a round of scoring we destribute points from a node to nodes it refers to.
|
|
|
|
|
// Returns true, iff scores were distributed.
|
|
|
|
|
//
|
|
|
|
|
bool scoreRound (std::vector<scoreNode>& vsnNodes)
|
|
|
|
|
bool UniqueNodeListImp::scoreRound (std::vector<scoreNode>& vsnNodes)
|
|
|
|
|
{
|
|
|
|
|
bool bDist = false;
|
|
|
|
|
|
|
|
|
|
@@ -890,7 +1077,7 @@ private:
|
|
|
|
|
//
|
|
|
|
|
// VFALCO TODO Shrink this function, break it up
|
|
|
|
|
//
|
|
|
|
|
void scoreCompute ()
|
|
|
|
|
void UniqueNodeListImp::scoreCompute()
|
|
|
|
|
{
|
|
|
|
|
hash_map<std::string, int> umPulicIdx; // Map of public key to index.
|
|
|
|
|
hash_map<std::string, int> umDomainIdx; // Map of domain to index.
|
|
|
|
|
@@ -1250,7 +1437,7 @@ private:
|
|
|
|
|
|
|
|
|
|
// Start a timer to update scores.
|
|
|
|
|
// <-- bNow: true, to force scoring for debugging.
|
|
|
|
|
void scoreNext (bool bNow)
|
|
|
|
|
void UniqueNodeListImp::scoreNext (bool bNow)
|
|
|
|
|
{
|
|
|
|
|
// WriteLog (lsTRACE, UniqueNodeList) << str(boost::format("scoreNext: mtpFetchUpdated=%s mtpScoreStart=%s mtpScoreUpdated=%s mtpScoreNext=%s") % mtpFetchUpdated % mtpScoreStart % mtpScoreUpdated % mtpScoreNext);
|
|
|
|
|
bool bCanScore = mtpScoreStart.is_not_a_date_time () // Not scoring.
|
|
|
|
|
@@ -1279,7 +1466,7 @@ private:
|
|
|
|
|
//
|
|
|
|
|
// VFALCO TODO Can't we take a filename or stream instead of a string?
|
|
|
|
|
//
|
|
|
|
|
bool responseFetch (std::string const& strDomain, const boost::system::error_code& err, int iStatus, std::string const& strSiteFile)
|
|
|
|
|
bool UniqueNodeListImp::responseFetch (std::string const& strDomain, const boost::system::error_code& err, int iStatus, std::string const& strSiteFile)
|
|
|
|
|
{
|
|
|
|
|
bool bReject = !err && iStatus != 200;
|
|
|
|
|
|
|
|
|
|
@@ -1399,7 +1586,7 @@ private:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Try to process the next fetch of a ripple.txt.
|
|
|
|
|
void fetchNext ()
|
|
|
|
|
void UniqueNodeListImp::fetchNext()
|
|
|
|
|
{
|
|
|
|
|
bool bFull;
|
|
|
|
|
|
|
|
|
|
@@ -1502,7 +1689,7 @@ private:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Called when we need to update scores.
|
|
|
|
|
void fetchDirty ()
|
|
|
|
|
void UniqueNodeListImp::fetchDirty()
|
|
|
|
|
{
|
|
|
|
|
// Note update.
|
|
|
|
|
mtpFetchUpdated = boost::posix_time::second_clock::universal_time ();
|
|
|
|
|
@@ -1515,7 +1702,7 @@ private:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void fetchFinish ()
|
|
|
|
|
void UniqueNodeListImp::fetchFinish()
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
ScopedFetchLockType sl (mFetchLock);
|
|
|
|
|
@@ -1528,7 +1715,7 @@ private:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Get the ripple.txt and process it.
|
|
|
|
|
void fetchProcess (std::string strDomain)
|
|
|
|
|
void UniqueNodeListImp::fetchProcess (std::string strDomain)
|
|
|
|
|
{
|
|
|
|
|
WriteLog (lsTRACE, UniqueNodeList) << strDomain
|
|
|
|
|
<< ": fetching " << node_file_name_ << ".";
|
|
|
|
|
@@ -1555,7 +1742,7 @@ private:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Process IniFileSections [validators_url].
|
|
|
|
|
void getValidatorsUrl (RippleAddress const& naNodePublic,
|
|
|
|
|
void UniqueNodeListImp::getValidatorsUrl (RippleAddress const& naNodePublic,
|
|
|
|
|
IniFileSections secSite)
|
|
|
|
|
{
|
|
|
|
|
std::string strValidatorsUrl;
|
|
|
|
|
@@ -1593,7 +1780,7 @@ private:
|
|
|
|
|
|
|
|
|
|
// Process IniFileSections [ips_url].
|
|
|
|
|
// If we have a IniFileSections with a single entry, fetch the url and process it.
|
|
|
|
|
void getIpsUrl (RippleAddress const& naNodePublic, IniFileSections secSite)
|
|
|
|
|
void UniqueNodeListImp::getIpsUrl (RippleAddress const& naNodePublic, IniFileSections secSite)
|
|
|
|
|
{
|
|
|
|
|
std::string strIpsUrl;
|
|
|
|
|
std::string strScheme;
|
|
|
|
|
@@ -1629,7 +1816,7 @@ private:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Given a IniFileSections with IPs, parse and persist it for a validator.
|
|
|
|
|
bool responseIps (std::string const& strSite, RippleAddress const& naNodePublic, const boost::system::error_code& err, int iStatus, std::string const& strIpsFile)
|
|
|
|
|
bool UniqueNodeListImp::responseIps (std::string const& strSite, RippleAddress const& naNodePublic, const boost::system::error_code& err, int iStatus, std::string const& strIpsFile)
|
|
|
|
|
{
|
|
|
|
|
bool bReject = !err && iStatus != 200;
|
|
|
|
|
|
|
|
|
|
@@ -1649,7 +1836,7 @@ private:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// After fetching a ripple.txt from a web site, given a IniFileSections with validators, parse and persist it.
|
|
|
|
|
bool responseValidators (std::string const& strValidatorsUrl, RippleAddress const& naNodePublic, IniFileSections secSite, std::string const& strSite, const boost::system::error_code& err, int iStatus, std::string const& strValidatorsFile)
|
|
|
|
|
bool UniqueNodeListImp::responseValidators (std::string const& strValidatorsUrl, RippleAddress const& naNodePublic, IniFileSections secSite, std::string const& strSite, const boost::system::error_code& err, int iStatus, std::string const& strValidatorsFile)
|
|
|
|
|
{
|
|
|
|
|
bool bReject = !err && iStatus != 200;
|
|
|
|
|
|
|
|
|
|
@@ -1674,7 +1861,7 @@ private:
|
|
|
|
|
// Persist the IPs refered to by a Validator.
|
|
|
|
|
// --> strSite: source of the IPs (for debugging)
|
|
|
|
|
// --> naNodePublic: public key of the validating node.
|
|
|
|
|
void processIps (std::string const& strSite, RippleAddress const& naNodePublic, IniFileSections::mapped_type* pmtVecStrIps)
|
|
|
|
|
void UniqueNodeListImp::processIps (std::string const& strSite, RippleAddress const& naNodePublic, IniFileSections::mapped_type* pmtVecStrIps)
|
|
|
|
|
{
|
|
|
|
|
std::string strEscNodePublic = sqlEscape (naNodePublic.humanNodePublic ());
|
|
|
|
|
|
|
|
|
|
@@ -1743,7 +1930,7 @@ private:
|
|
|
|
|
// --> strValidatorsSrc: source details for display
|
|
|
|
|
// --> naNodePublic: remote source public key - not valid for local
|
|
|
|
|
// --> vsWhy: reason for adding validator to SeedDomains or SeedNodes.
|
|
|
|
|
int processValidators (std::string const& strSite, std::string const& strValidatorsSrc, RippleAddress const& naNodePublic, ValidatorSource vsWhy, IniFileSections::mapped_type* pmtVecStrValidators)
|
|
|
|
|
int UniqueNodeListImp::processValidators (std::string const& strSite, std::string const& strValidatorsSrc, RippleAddress const& naNodePublic, ValidatorSource vsWhy, IniFileSections::mapped_type* pmtVecStrValidators)
|
|
|
|
|
{
|
|
|
|
|
std::string strNodePublic = naNodePublic.isValid () ? naNodePublic.humanNodePublic () : strValidatorsSrc;
|
|
|
|
|
int iValues = 0;
|
|
|
|
|
@@ -1842,7 +2029,7 @@ private:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Process a ripple.txt.
|
|
|
|
|
void processFile (std::string const& strDomain, RippleAddress const& naNodePublic, IniFileSections secSite)
|
|
|
|
|
void UniqueNodeListImp::processFile (std::string const& strDomain, RippleAddress const& naNodePublic, IniFileSections secSite)
|
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
// Process Validators
|
|
|
|
|
@@ -1872,7 +2059,7 @@ private:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Retrieve a SeedDomain from DB.
|
|
|
|
|
bool getSeedDomains (std::string const& strDomain, seedDomain& dstSeedDomain)
|
|
|
|
|
bool UniqueNodeListImp::getSeedDomains (std::string const& strDomain, seedDomain& dstSeedDomain)
|
|
|
|
|
{
|
|
|
|
|
bool bResult = false;
|
|
|
|
|
|
|
|
|
|
@@ -1955,7 +2142,7 @@ private:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Persist a SeedDomain.
|
|
|
|
|
void setSeedDomains (const seedDomain& sdSource, bool bNext)
|
|
|
|
|
void UniqueNodeListImp::setSeedDomains (const seedDomain& sdSource, bool bNext)
|
|
|
|
|
{
|
|
|
|
|
int iNext = iToSeconds (sdSource.tpNext);
|
|
|
|
|
int iScan = iToSeconds (sdSource.tpScan);
|
|
|
|
|
@@ -1997,7 +2184,7 @@ private:
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Retrieve a SeedNode from DB.
|
|
|
|
|
bool getSeedNodes (RippleAddress const& naNodePublic, seedNode& dstSeedNode)
|
|
|
|
|
bool UniqueNodeListImp::getSeedNodes (RippleAddress const& naNodePublic, seedNode& dstSeedNode)
|
|
|
|
|
{
|
|
|
|
|
std::string strSql =
|
|
|
|
|
str (boost::format (
|
|
|
|
|
@@ -2064,7 +2251,7 @@ private:
|
|
|
|
|
|
|
|
|
|
// Persist a SeedNode.
|
|
|
|
|
// <-- bNext: true, to do fetching if needed.
|
|
|
|
|
void setSeedNodes (const seedNode& snSource, bool bNext)
|
|
|
|
|
void UniqueNodeListImp::setSeedNodes (const seedNode& snSource, bool bNext)
|
|
|
|
|
{
|
|
|
|
|
int iNext = iToSeconds (snSource.tpNext);
|
|
|
|
|
int iScan = iToSeconds (snSource.tpScan);
|
|
|
|
|
@@ -2113,7 +2300,7 @@ private:
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
bool validatorsResponse (const boost::system::error_code& err, int iStatus, std::string strResponse)
|
|
|
|
|
bool UniqueNodeListImp::validatorsResponse (const boost::system::error_code& err, int iStatus, std::string strResponse)
|
|
|
|
|
{
|
|
|
|
|
bool bReject = !err && iStatus != 200;
|
|
|
|
|
|
|
|
|
|
@@ -2133,7 +2320,6 @@ private:
|
|
|
|
|
WriteLog (lsWARNING, UniqueNodeList) << "Error: " << err.message ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bReject;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2145,7 +2331,7 @@ private:
|
|
|
|
|
//
|
|
|
|
|
// VFALCO TODO Can't we name this processValidatorList?
|
|
|
|
|
//
|
|
|
|
|
void nodeProcess (std::string const& strSite, std::string const& strValidators, std::string const& strSource)
|
|
|
|
|
void UniqueNodeListImp::nodeProcess (std::string const& strSite, std::string const& strValidators, std::string const& strSource)
|
|
|
|
|
{
|
|
|
|
|
IniFileSections secValidators = parseIniFile (strValidators, true);
|
|
|
|
|
|
|
|
|
|
@@ -2164,45 +2350,6 @@ private:
|
|
|
|
|
% getConfig ().VALIDATORS_BASE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
using FetchLockType = RippleMutex;
|
|
|
|
|
using ScopedFetchLockType = std::lock_guard <FetchLockType>;
|
|
|
|
|
FetchLockType mFetchLock;
|
|
|
|
|
|
|
|
|
|
using UNLLockType = RippleRecursiveMutex;
|
|
|
|
|
using ScopedUNLLockType = std::lock_guard <UNLLockType>;
|
|
|
|
|
UNLLockType mUNLLock;
|
|
|
|
|
|
|
|
|
|
// VFALCO TODO Replace ptime with beast::Time
|
|
|
|
|
// Misc persistent information
|
|
|
|
|
boost::posix_time::ptime mtpScoreUpdated;
|
|
|
|
|
boost::posix_time::ptime mtpFetchUpdated;
|
|
|
|
|
|
|
|
|
|
// XXX Make this faster, make this the contents vector unsigned char or raw public key.
|
|
|
|
|
// XXX Contents needs to based on score.
|
|
|
|
|
hash_set<std::string> mUNL;
|
|
|
|
|
|
|
|
|
|
boost::posix_time::ptime mtpScoreNext; // When to start scoring.
|
|
|
|
|
boost::posix_time::ptime mtpScoreStart; // Time currently started scoring.
|
|
|
|
|
beast::DeadlineTimer m_scoreTimer; // Timer to start scoring.
|
|
|
|
|
|
|
|
|
|
int mFetchActive; // Count of active fetches.
|
|
|
|
|
|
|
|
|
|
boost::posix_time::ptime mtpFetchNext; // Time of to start next fetch.
|
|
|
|
|
beast::DeadlineTimer m_fetchTimer; // Timer to start fetching.
|
|
|
|
|
|
|
|
|
|
std::map<RippleAddress, ClusterNodeStatus> m_clusterNodes;
|
|
|
|
|
|
|
|
|
|
std::string node_file_name_;
|
|
|
|
|
std::string node_file_path_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
UniqueNodeList::UniqueNodeList (Stoppable& parent)
|
|
|
|
|
: Stoppable ("UniqueNodeList", parent)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|