mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Change RPC unl_default to unl_load & unl_network and add UNL bootstrapping.
This commit is contained in:
@@ -73,7 +73,7 @@ void Application::run()
|
||||
//
|
||||
// Allow peer connections.
|
||||
//
|
||||
if(!theConfig.PEER_IP.empty() && theConfig.PEER_PORT)
|
||||
if (!theConfig.PEER_IP.empty() && theConfig.PEER_PORT)
|
||||
{
|
||||
mPeerDoor = new PeerDoor(mIOService);
|
||||
}
|
||||
@@ -85,7 +85,7 @@ void Application::run()
|
||||
//
|
||||
// Allow RPC connections.
|
||||
//
|
||||
if(!theConfig.RPC_IP.empty() && theConfig.RPC_PORT)
|
||||
if (!theConfig.RPC_IP.empty() && theConfig.RPC_PORT)
|
||||
{
|
||||
mRPCDoor = new RPCDoor(mIOService);
|
||||
}
|
||||
@@ -122,7 +122,8 @@ void Application::run()
|
||||
|
||||
mNetOps.setStateTimer(0);
|
||||
|
||||
// temporary
|
||||
getUNL().nodeBootstrap();
|
||||
|
||||
mIOService.run(); // This blocks
|
||||
|
||||
std::cout << "Done." << std::endl;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
@@ -25,14 +24,6 @@
|
||||
#include "NicknameState.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define VALIDATORS_FETCH_SECONDS 30
|
||||
#define VALIDATORS_FILE_PATH "/" VALIDATORS_FILE_NAME
|
||||
#define VALIDATORS_FILE_BYTES_MAX (50 << 10)
|
||||
|
||||
/*
|
||||
Just read from wire until the entire request is in.
|
||||
*/
|
||||
|
||||
RPCServer::RPCServer(boost::asio::io_service& io_service , NetworkOPs* nopNetwork)
|
||||
: mNetOps(nopNetwork), mSocket(io_service)
|
||||
{
|
||||
@@ -1902,75 +1893,6 @@ Json::Value RPCServer::doWalletSeed(Json::Value& params)
|
||||
}
|
||||
}
|
||||
|
||||
void RPCServer::validatorsResponse(const boost::system::error_code& err, std::string strResponse)
|
||||
{
|
||||
std::cerr << "Fetch '" VALIDATORS_FILE_NAME "' complete." << std::endl;
|
||||
|
||||
if (!err)
|
||||
{
|
||||
theApp->getUNL().nodeDefault(strResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error: " << err.message() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Populate the UNL from a validators.txt file.
|
||||
Json::Value RPCServer::doUnlDefault(Json::Value& params) {
|
||||
if (!params.size() || (1==params.size() && !params[0u].compare("network")))
|
||||
{
|
||||
bool bNetwork = 1 == params.size();
|
||||
std::string strValidators;
|
||||
|
||||
if (!bNetwork)
|
||||
{
|
||||
std::ifstream ifsDefault(VALIDATORS_FILE_NAME, std::ios::in);
|
||||
|
||||
if (!ifsDefault)
|
||||
{
|
||||
std::cerr << "Failed to open '" VALIDATORS_FILE_NAME "'." << std::endl;
|
||||
|
||||
bNetwork = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
strValidators.assign((std::istreambuf_iterator<char>(ifsDefault)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
if (ifsDefault.bad())
|
||||
{
|
||||
std::cerr << "Failed to read '" VALIDATORS_FILE_NAME "'." << std::endl;
|
||||
|
||||
bNetwork = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bNetwork)
|
||||
{
|
||||
HttpsClient::httpsGet(
|
||||
theApp->getIOService(),
|
||||
VALIDATORS_SITE,
|
||||
443,
|
||||
VALIDATORS_FILE_PATH,
|
||||
VALIDATORS_FILE_BYTES_MAX,
|
||||
boost::posix_time::seconds(VALIDATORS_FETCH_SECONDS),
|
||||
boost::bind(&RPCServer::validatorsResponse, this, _1, _2));
|
||||
|
||||
return "fetching " VALIDATORS_FILE_NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
theApp->getUNL().nodeDefault(strValidators);
|
||||
|
||||
return "processing " VALIDATORS_FILE_NAME;
|
||||
}
|
||||
}
|
||||
else
|
||||
return RPCError(rpcINVALID_PARAMS);
|
||||
}
|
||||
|
||||
// unl_delete <domain>|<public_key>
|
||||
Json::Value RPCServer::doUnlDelete(Json::Value& params)
|
||||
{
|
||||
@@ -1995,19 +1917,42 @@ Json::Value RPCServer::doUnlDelete(Json::Value& params)
|
||||
Json::Value RPCServer::doUnlList(Json::Value& params)
|
||||
{
|
||||
Json::Value obj(Json::objectValue);
|
||||
|
||||
obj["unl"]=theApp->getUNL().getUnlJson();
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Populate the UNL from a local validators.txt file.
|
||||
Json::Value RPCServer::doUnlLoad(Json::Value& params)
|
||||
{
|
||||
if (!theApp->getUNL().nodeLoad())
|
||||
{
|
||||
return RPCError(rpcLOAD_FAILED);
|
||||
}
|
||||
|
||||
return "loading";
|
||||
}
|
||||
|
||||
// Populate the UNL from newcoin.org's validators.txt file.
|
||||
Json::Value RPCServer::doUnlNetwork(Json::Value& params)
|
||||
{
|
||||
theApp->getUNL().nodeNetwork();
|
||||
|
||||
return "fetching";
|
||||
}
|
||||
|
||||
// unl_reset
|
||||
Json::Value RPCServer::doUnlReset(Json::Value& params) {
|
||||
Json::Value RPCServer::doUnlReset(Json::Value& params)
|
||||
{
|
||||
theApp->getUNL().nodeReset();
|
||||
|
||||
return "removing nodes";
|
||||
}
|
||||
|
||||
// unl_score
|
||||
Json::Value RPCServer::doUnlScore(Json::Value& params) {
|
||||
Json::Value RPCServer::doUnlScore(Json::Value& params)
|
||||
{
|
||||
theApp->getUNL().nodeScore();
|
||||
|
||||
return "scoring requested";
|
||||
@@ -2053,9 +1998,10 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
|
||||
{ "tx", &RPCServer::doTx, 1, 1, },
|
||||
|
||||
{ "unl_add", &RPCServer::doUnlAdd, 1, 2, },
|
||||
{ "unl_default", &RPCServer::doUnlDefault, 0, 1, },
|
||||
{ "unl_delete", &RPCServer::doUnlDelete, 1, 1, },
|
||||
{ "unl_list", &RPCServer::doUnlList, 0, 0, },
|
||||
{ "unl_load", &RPCServer::doUnlLoad, 0, 0, },
|
||||
{ "unl_network", &RPCServer::doUnlNetwork, 0, 0, },
|
||||
{ "unl_reset", &RPCServer::doUnlReset, 0, 0, },
|
||||
{ "unl_score", &RPCServer::doUnlScore, 0, 0, },
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ public:
|
||||
enum {
|
||||
rpcSUCCESS,
|
||||
|
||||
// Misc failure
|
||||
rpcLOAD_FAILED,
|
||||
|
||||
// Networking
|
||||
rpcNO_CLOSED,
|
||||
rpcNO_CURRENT,
|
||||
@@ -40,7 +43,7 @@ public:
|
||||
rpcINVALID_PARAMS,
|
||||
rpcUNKNOWN_COMMAND,
|
||||
|
||||
// Bad paramater
|
||||
// Bad parameter
|
||||
rpcACT_MALFORMED,
|
||||
rpcBAD_SEED,
|
||||
rpcDST_ACT_MALFORMED,
|
||||
@@ -131,10 +134,11 @@ private:
|
||||
Json::Value doTx(Json::Value& params);
|
||||
|
||||
Json::Value doUnlAdd(Json::Value& params);
|
||||
Json::Value doUnlDefault(Json::Value& params);
|
||||
Json::Value doUnlDelete(Json::Value& params);
|
||||
Json::Value doUnlFetch(Json::Value& params);
|
||||
Json::Value doUnlList(Json::Value& params);
|
||||
Json::Value doUnlLoad(Json::Value& params);
|
||||
Json::Value doUnlNetwork(Json::Value& params);
|
||||
Json::Value doUnlReset(Json::Value& params);
|
||||
Json::Value doUnlScore(Json::Value& params);
|
||||
|
||||
@@ -151,8 +155,6 @@ private:
|
||||
Json::Value doWalletUnlock(Json::Value& params);
|
||||
Json::Value doWalletVerify(Json::Value& params);
|
||||
|
||||
void validatorsResponse(const boost::system::error_code& err, std::string strResponse);
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<RPCServer> pointer;
|
||||
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
#include <boost/mem_fn.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#define VALIDATORS_FETCH_SECONDS 30
|
||||
#define VALIDATORS_FILE_PATH "/" VALIDATORS_FILE_NAME
|
||||
#define VALIDATORS_FILE_BYTES_MAX (50 << 10)
|
||||
|
||||
// Gather string constants.
|
||||
#define SECTION_CURRENCIES "currencies"
|
||||
#define SECTION_DOMAIN "domain"
|
||||
@@ -1409,6 +1416,116 @@ Json::Value UniqueNodeList::getUnlJson()
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool UniqueNodeList::nodeLoad()
|
||||
{
|
||||
if (theConfig.UNL_DEFAULT.empty())
|
||||
{
|
||||
std::cerr << "UNL_DEFAULT not specified." << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!boost::filesystem::exists(theConfig.UNL_DEFAULT))
|
||||
{
|
||||
std::cerr << str(boost::format("UNL_DEFAULT not found: '%s'") % theConfig.UNL_DEFAULT) << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!boost::filesystem::is_regular_file(theConfig.UNL_DEFAULT))
|
||||
{
|
||||
std::cerr << str(boost::format("UNL_DEFAULT not regular file: '%s'") % theConfig.UNL_DEFAULT) << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream ifsDefault(theConfig.UNL_DEFAULT.native().c_str(), std::ios::in);
|
||||
|
||||
if (!ifsDefault)
|
||||
{
|
||||
std::cerr << str(boost::format("Failed to open: '%s'") % theConfig.UNL_DEFAULT) << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string strValidators;
|
||||
|
||||
strValidators.assign((std::istreambuf_iterator<char>(ifsDefault)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
if (ifsDefault.bad())
|
||||
{
|
||||
std::cerr << str(boost::format("Failed to read: '%s'") % theConfig.UNL_DEFAULT) << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
nodeDefault(strValidators);
|
||||
|
||||
std::cerr << str(boost::format("Processing: '%s'") % theConfig.UNL_DEFAULT) << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UniqueNodeList::validatorsResponse(const boost::system::error_code& err, std::string strResponse)
|
||||
{
|
||||
std::cerr << "Fetch '" VALIDATORS_FILE_NAME "' complete." << std::endl;
|
||||
|
||||
if (!err)
|
||||
{
|
||||
nodeDefault(strResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error: " << err.message() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void UniqueNodeList::nodeNetwork()
|
||||
{
|
||||
HttpsClient::httpsGet(
|
||||
theApp->getIOService(),
|
||||
VALIDATORS_SITE,
|
||||
443,
|
||||
VALIDATORS_FILE_PATH,
|
||||
VALIDATORS_FILE_BYTES_MAX,
|
||||
boost::posix_time::seconds(VALIDATORS_FETCH_SECONDS),
|
||||
boost::bind(&UniqueNodeList::validatorsResponse, this, _1, _2));
|
||||
}
|
||||
|
||||
void UniqueNodeList::nodeBootstrap()
|
||||
{
|
||||
int iDomains = 0;
|
||||
int iNodes = 0;
|
||||
|
||||
{
|
||||
Database* db=theApp->getWalletDB()->getDB();
|
||||
|
||||
ScopedLock sl(theApp->getWalletDB()->getDBLock());
|
||||
|
||||
if (db->executeSQL("SELECT COUNT(*) AS Count FROM SeedDomains;") && db->startIterRows())
|
||||
iDomains = db->getInt("Count");
|
||||
|
||||
if (db->executeSQL("SELECT COUNT(*) AS Count FROM SeedNodes;") && db->startIterRows())
|
||||
iNodes = db->getInt("Count");
|
||||
}
|
||||
|
||||
bool bLoaded = iDomains || iNodes;
|
||||
|
||||
if (!bLoaded && !theConfig.UNL_DEFAULT.empty())
|
||||
{
|
||||
std::cerr << "Bootstrapping UNL: loading from file." << std::endl;
|
||||
|
||||
bLoaded = nodeLoad();
|
||||
}
|
||||
|
||||
if (!bLoaded)
|
||||
{
|
||||
std::cerr << "Bootstrapping UNL: loading from " VALIDATORS_SITE "." << std::endl;
|
||||
nodeNetwork();
|
||||
}
|
||||
}
|
||||
|
||||
// Process a validators.txt.
|
||||
// --> strValidators: a validators.txt
|
||||
void UniqueNodeList::nodeDefault(const std::string& strValidators) {
|
||||
|
||||
@@ -131,6 +131,8 @@ private:
|
||||
bool getSeedNodes(const NewcoinAddress& naNodePublic, seedNode& dstSeedNode);
|
||||
void setSeedNodes(const seedNode& snSource, bool bNext);
|
||||
|
||||
void validatorsResponse(const boost::system::error_code& err, std::string strResponse);
|
||||
|
||||
public:
|
||||
UniqueNodeList(boost::asio::io_service& io_service);
|
||||
|
||||
@@ -148,6 +150,10 @@ public:
|
||||
|
||||
bool nodeInUNL(const NewcoinAddress& naNodePublic);
|
||||
|
||||
void nodeBootstrap();
|
||||
bool nodeLoad();
|
||||
void nodeNetwork();
|
||||
|
||||
Json::Value getUnlJson();
|
||||
};
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ void printHelp(const po::options_description& desc)
|
||||
cout << " unl_add <domain>|<public> [<comment>]" << endl;
|
||||
cout << " unl_delete <domain>|<public_key>" << endl;
|
||||
cout << " unl_list" << endl;
|
||||
cout << " unl_load" << endl;
|
||||
cout << " unl_network" << endl;
|
||||
cout << " unl_reset" << endl;
|
||||
cout << " validation_create [<seed>|<pass_phrase>|<key>]" << endl;
|
||||
cout << " validation_seed [<seed>|<pass_phrase>|<key>]" << endl;
|
||||
|
||||
Reference in New Issue
Block a user