Merge pull request #1549 from TheBlueMatt/addnoderpc
Addnode optimization and addnode access via RPC
This commit is contained in:
commit
79bec38cb4
|
@ -201,6 +201,8 @@ static const CRPCCommand vRPCCommands[] =
|
||||||
{ "getblockcount", &getblockcount, true, false },
|
{ "getblockcount", &getblockcount, true, false },
|
||||||
{ "getconnectioncount", &getconnectioncount, true, false },
|
{ "getconnectioncount", &getconnectioncount, true, false },
|
||||||
{ "getpeerinfo", &getpeerinfo, true, false },
|
{ "getpeerinfo", &getpeerinfo, true, false },
|
||||||
|
{ "addnode", &addnode, true, true },
|
||||||
|
{ "getaddednodeinfo", &getaddednodeinfo, true, true },
|
||||||
{ "getdifficulty", &getdifficulty, true, false },
|
{ "getdifficulty", &getdifficulty, true, false },
|
||||||
{ "getgenerate", &getgenerate, true, false },
|
{ "getgenerate", &getgenerate, true, false },
|
||||||
{ "setgenerate", &setgenerate, true, false },
|
{ "setgenerate", &setgenerate, true, false },
|
||||||
|
@ -1179,6 +1181,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
|
||||||
// Special case non-string parameter types
|
// Special case non-string parameter types
|
||||||
//
|
//
|
||||||
if (strMethod == "stop" && n > 0) ConvertTo<bool>(params[0]);
|
if (strMethod == "stop" && n > 0) ConvertTo<bool>(params[0]);
|
||||||
|
if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo<bool>(params[0]);
|
||||||
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
|
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
|
||||||
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
|
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
|
||||||
|
|
|
@ -132,6 +132,8 @@ extern void EnsureWalletIsUnlocked();
|
||||||
|
|
||||||
extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp
|
extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp
|
||||||
extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp);
|
||||||
|
extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp);
|
||||||
|
extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
|
extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
|
||||||
extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp);
|
||||||
|
|
||||||
|
|
57
src/net.cpp
57
src/net.cpp
|
@ -72,6 +72,9 @@ CCriticalSection cs_vOneShots;
|
||||||
set<CNetAddr> setservAddNodeAddresses;
|
set<CNetAddr> setservAddNodeAddresses;
|
||||||
CCriticalSection cs_setservAddNodeAddresses;
|
CCriticalSection cs_setservAddNodeAddresses;
|
||||||
|
|
||||||
|
vector<std::string> vAddedNodes;
|
||||||
|
CCriticalSection cs_vAddedNodes;
|
||||||
|
|
||||||
static CSemaphore *semOutbound = NULL;
|
static CSemaphore *semOutbound = NULL;
|
||||||
|
|
||||||
void AddOneShot(string strDest)
|
void AddOneShot(string strDest)
|
||||||
|
@ -1523,16 +1526,26 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||||
{
|
{
|
||||||
printf("ThreadOpenAddedConnections started\n");
|
printf("ThreadOpenAddedConnections started\n");
|
||||||
|
|
||||||
if (mapArgs.count("-addnode") == 0)
|
{
|
||||||
return;
|
LOCK(cs_vAddedNodes);
|
||||||
|
vAddedNodes = mapMultiArgs["-addnode"];
|
||||||
|
}
|
||||||
|
|
||||||
if (HaveNameProxy()) {
|
if (HaveNameProxy()) {
|
||||||
while(!fShutdown) {
|
while(!fShutdown) {
|
||||||
BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
|
list<string> lAddresses(0);
|
||||||
|
{
|
||||||
|
LOCK(cs_vAddedNodes);
|
||||||
|
BOOST_FOREACH(string& strAddNode, vAddedNodes)
|
||||||
|
lAddresses.push_back(strAddNode);
|
||||||
|
}
|
||||||
|
BOOST_FOREACH(string& strAddNode, lAddresses) {
|
||||||
CAddress addr;
|
CAddress addr;
|
||||||
CSemaphoreGrant grant(*semOutbound);
|
CSemaphoreGrant grant(*semOutbound);
|
||||||
OpenNetworkConnection(addr, &grant, strAddNode.c_str());
|
OpenNetworkConnection(addr, &grant, strAddNode.c_str());
|
||||||
Sleep(500);
|
Sleep(500);
|
||||||
|
if (fShutdown)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
|
vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
|
||||||
Sleep(120000); // Retry every 2 minutes
|
Sleep(120000); // Retry every 2 minutes
|
||||||
|
@ -1541,41 +1554,47 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<vector<CService> > vservAddressesToAdd(0);
|
for (unsigned int i = 0; true; i++)
|
||||||
BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
|
|
||||||
{
|
{
|
||||||
vector<CService> vservNode(0);
|
list<string> lAddresses(0);
|
||||||
if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
|
|
||||||
{
|
{
|
||||||
vservAddressesToAdd.push_back(vservNode);
|
LOCK(cs_vAddedNodes);
|
||||||
|
BOOST_FOREACH(string& strAddNode, vAddedNodes)
|
||||||
|
lAddresses.push_back(strAddNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
list<vector<CService> > lservAddressesToAdd(0);
|
||||||
|
BOOST_FOREACH(string& strAddNode, lAddresses)
|
||||||
|
{
|
||||||
|
vector<CService> vservNode(0);
|
||||||
|
if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
|
||||||
{
|
{
|
||||||
LOCK(cs_setservAddNodeAddresses);
|
lservAddressesToAdd.push_back(vservNode);
|
||||||
BOOST_FOREACH(CService& serv, vservNode)
|
{
|
||||||
setservAddNodeAddresses.insert(serv);
|
LOCK(cs_setservAddNodeAddresses);
|
||||||
|
BOOST_FOREACH(CService& serv, vservNode)
|
||||||
|
setservAddNodeAddresses.insert(serv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
loop
|
|
||||||
{
|
|
||||||
vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
|
|
||||||
// Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
|
// Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
|
||||||
// (keeping in mind that addnode entries can have many IPs if fNameLookup)
|
// (keeping in mind that addnode entries can have many IPs if fNameLookup)
|
||||||
{
|
{
|
||||||
LOCK(cs_vNodes);
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
|
for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
|
||||||
BOOST_FOREACH(CService& addrNode, *(it))
|
BOOST_FOREACH(CService& addrNode, *(it))
|
||||||
if (pnode->addr == addrNode)
|
if (pnode->addr == addrNode)
|
||||||
{
|
{
|
||||||
it = vservConnectAddresses.erase(it);
|
it = lservAddressesToAdd.erase(it);
|
||||||
it--;
|
it--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
|
BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
|
||||||
{
|
{
|
||||||
CSemaphoreGrant grant(*semOutbound);
|
CSemaphoreGrant grant(*semOutbound);
|
||||||
OpenNetworkConnection(CAddress(*(vserv.begin())), &grant);
|
OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
|
||||||
Sleep(500);
|
Sleep(500);
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -102,6 +102,9 @@ extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
|
||||||
extern CCriticalSection cs_mapRelay;
|
extern CCriticalSection cs_mapRelay;
|
||||||
extern std::map<CInv, int64> mapAlreadyAskedFor;
|
extern std::map<CInv, int64> mapAlreadyAskedFor;
|
||||||
|
|
||||||
|
extern std::vector<std::string> vAddedNodes;
|
||||||
|
extern CCriticalSection cs_vAddedNodes;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
134
src/rpcnet.cpp
134
src/rpcnet.cpp
|
@ -65,3 +65,137 @@ Value getpeerinfo(const Array& params, bool fHelp)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value addnode(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
string strCommand;
|
||||||
|
if (params.size() == 2)
|
||||||
|
strCommand = params[1].get_str();
|
||||||
|
if (fHelp || params.size() != 2 ||
|
||||||
|
(strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
|
||||||
|
throw runtime_error(
|
||||||
|
"addnode <node> <add|remove|onetry>\n"
|
||||||
|
"Attempts add or remove <node> from the addnode list or try a connection to <node> once.");
|
||||||
|
|
||||||
|
string strNode = params[0].get_str();
|
||||||
|
|
||||||
|
if (strCommand == "onetry")
|
||||||
|
{
|
||||||
|
CAddress addr;
|
||||||
|
ConnectNode(addr, strNode.c_str());
|
||||||
|
return Value::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK(cs_vAddedNodes);
|
||||||
|
vector<string>::iterator it = vAddedNodes.begin();
|
||||||
|
for(; it != vAddedNodes.end(); it++)
|
||||||
|
if (strNode == *it)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (strCommand == "add")
|
||||||
|
{
|
||||||
|
if (it != vAddedNodes.end())
|
||||||
|
throw JSONRPCError(-23, "Error: Node already added");
|
||||||
|
vAddedNodes.push_back(strNode);
|
||||||
|
}
|
||||||
|
else if(strCommand == "remove")
|
||||||
|
{
|
||||||
|
if (it == vAddedNodes.end())
|
||||||
|
throw JSONRPCError(-24, "Error: Node has not been added.");
|
||||||
|
vAddedNodes.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Value::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value getaddednodeinfo(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||||
|
throw runtime_error(
|
||||||
|
"getaddednodeinfo <dns> [node]\n"
|
||||||
|
"Returns information about the given added node, or all added nodes\n"
|
||||||
|
"(note that onetry addnodes are not listed here)\n"
|
||||||
|
"If dns is false, only a list of added nodes will be provided,\n"
|
||||||
|
"otherwise connected information will also be available.");
|
||||||
|
|
||||||
|
bool fDns = params[0].get_bool();
|
||||||
|
|
||||||
|
list<string> laddedNodes(0);
|
||||||
|
if (params.size() == 1)
|
||||||
|
{
|
||||||
|
LOCK(cs_vAddedNodes);
|
||||||
|
BOOST_FOREACH(string& strAddNode, vAddedNodes)
|
||||||
|
laddedNodes.push_back(strAddNode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string strNode = params[1].get_str();
|
||||||
|
LOCK(cs_vAddedNodes);
|
||||||
|
BOOST_FOREACH(string& strAddNode, vAddedNodes)
|
||||||
|
if (strAddNode == strNode)
|
||||||
|
{
|
||||||
|
laddedNodes.push_back(strAddNode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (laddedNodes.size() == 0)
|
||||||
|
throw JSONRPCError(-24, "Error: Node has not been added.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fDns)
|
||||||
|
{
|
||||||
|
Object ret;
|
||||||
|
BOOST_FOREACH(string& strAddNode, laddedNodes)
|
||||||
|
ret.push_back(Pair("addednode", strAddNode));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array ret;
|
||||||
|
|
||||||
|
list<pair<string, vector<CService> > > laddedAddreses(0);
|
||||||
|
BOOST_FOREACH(string& strAddNode, laddedNodes)
|
||||||
|
{
|
||||||
|
vector<CService> vservNode(0);
|
||||||
|
if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
|
||||||
|
laddedAddreses.push_back(make_pair(strAddNode, vservNode));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Object obj;
|
||||||
|
obj.push_back(Pair("addednode", strAddNode));
|
||||||
|
obj.push_back(Pair("connected", false));
|
||||||
|
Array addresses;
|
||||||
|
obj.push_back(Pair("addresses", addresses));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK(cs_vNodes);
|
||||||
|
for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
|
||||||
|
{
|
||||||
|
Object obj;
|
||||||
|
obj.push_back(Pair("addednode", it->first));
|
||||||
|
|
||||||
|
Array addresses;
|
||||||
|
bool fConnected = false;
|
||||||
|
BOOST_FOREACH(CService& addrNode, it->second)
|
||||||
|
{
|
||||||
|
bool fFound = false;
|
||||||
|
Object node;
|
||||||
|
node.push_back(Pair("address", addrNode.ToString()));
|
||||||
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
|
if (pnode->addr == addrNode)
|
||||||
|
{
|
||||||
|
fFound = true;
|
||||||
|
fConnected = true;
|
||||||
|
node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!fFound)
|
||||||
|
node.push_back(Pair("connected", "false"));
|
||||||
|
addresses.push_back(node);
|
||||||
|
}
|
||||||
|
obj.push_back(Pair("connected", fConnected));
|
||||||
|
obj.push_back(Pair("addresses", addresses));
|
||||||
|
ret.push_back(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue