net: Add most functions needed for vNodes to CConnman
This commit is contained in:
parent
8ae2dac1c6
commit
c0569c7fa1
8 changed files with 121 additions and 46 deletions
66
src/net.cpp
66
src/net.cpp
|
@ -2267,6 +2267,72 @@ bool CConnman::RemoveAddedNode(const std::string& strNode)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t CConnman::GetNodeCount(NumConnections flags)
|
||||||
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
|
if (flags == CConnman::CONNECTIONS_ALL) // Shortcut if we want total
|
||||||
|
return vNodes.size();
|
||||||
|
|
||||||
|
int nNum = 0;
|
||||||
|
for(std::vector<CNode*>::const_iterator it = vNodes.begin(); it != vNodes.end(); ++it)
|
||||||
|
if (flags & ((*it)->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT))
|
||||||
|
nNum++;
|
||||||
|
|
||||||
|
return nNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats)
|
||||||
|
{
|
||||||
|
vstats.clear();
|
||||||
|
LOCK(cs_vNodes);
|
||||||
|
vstats.reserve(vNodes.size());
|
||||||
|
for(std::vector<CNode*>::iterator it = vNodes.begin(); it != vNodes.end(); ++it) {
|
||||||
|
CNode* pnode = *it;
|
||||||
|
CNodeStats stats;
|
||||||
|
pnode->copyStats(stats);
|
||||||
|
vstats.push_back(stats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConnman::DisconnectAddress(const CNetAddr& netAddr)
|
||||||
|
{
|
||||||
|
if (CNode* pnode = FindNode(netAddr)) {
|
||||||
|
pnode->fDisconnect = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConnman::DisconnectSubnet(const CSubNet& subNet)
|
||||||
|
{
|
||||||
|
if (CNode* pnode = FindNode(subNet)) {
|
||||||
|
pnode->fDisconnect = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConnman::DisconnectNode(const std::string& strNode)
|
||||||
|
{
|
||||||
|
if (CNode* pnode = FindNode(strNode)) {
|
||||||
|
pnode->fDisconnect = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConnman::DisconnectNode(NodeId id)
|
||||||
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
|
for(CNode* pnode : vNodes) {
|
||||||
|
if (id == pnode->id) {
|
||||||
|
pnode->fDisconnect = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void RelayTransaction(const CTransaction& tx)
|
void RelayTransaction(const CTransaction& tx)
|
||||||
{
|
{
|
||||||
CInv inv(MSG_TX, tx.GetHash());
|
CInv inv(MSG_TX, tx.GetHash());
|
||||||
|
|
16
src/net.h
16
src/net.h
|
@ -101,9 +101,18 @@ CNode* FindNode(const std::string& addrName);
|
||||||
CNode* FindNode(const CService& ip);
|
CNode* FindNode(const CService& ip);
|
||||||
CNode* FindNode(const NodeId id); //TODO: Remove this
|
CNode* FindNode(const NodeId id); //TODO: Remove this
|
||||||
|
|
||||||
|
class CNodeStats;
|
||||||
class CConnman
|
class CConnman
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum NumConnections {
|
||||||
|
CONNECTIONS_NONE = 0,
|
||||||
|
CONNECTIONS_IN = (1U << 0),
|
||||||
|
CONNECTIONS_OUT = (1U << 1),
|
||||||
|
CONNECTIONS_ALL = (CONNECTIONS_IN | CONNECTIONS_OUT),
|
||||||
|
};
|
||||||
|
|
||||||
CConnman();
|
CConnman();
|
||||||
~CConnman();
|
~CConnman();
|
||||||
bool Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError);
|
bool Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError);
|
||||||
|
@ -150,6 +159,13 @@ public:
|
||||||
bool RemoveAddedNode(const std::string& node);
|
bool RemoveAddedNode(const std::string& node);
|
||||||
std::vector<AddedNodeInfo> GetAddedNodeInfo();
|
std::vector<AddedNodeInfo> GetAddedNodeInfo();
|
||||||
|
|
||||||
|
size_t GetNodeCount(NumConnections num);
|
||||||
|
void GetNodeStats(std::vector<CNodeStats>& vstats);
|
||||||
|
bool DisconnectAddress(const CNetAddr& addr);
|
||||||
|
bool DisconnectNode(const std::string& node);
|
||||||
|
bool DisconnectNode(NodeId id);
|
||||||
|
bool DisconnectSubnet(const CSubNet& subnet);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ListenSocket {
|
struct ListenSocket {
|
||||||
SOCKET socket;
|
SOCKET socket;
|
||||||
|
|
|
@ -50,16 +50,18 @@ ClientModel::~ClientModel()
|
||||||
|
|
||||||
int ClientModel::getNumConnections(unsigned int flags) const
|
int ClientModel::getNumConnections(unsigned int flags) const
|
||||||
{
|
{
|
||||||
LOCK(cs_vNodes);
|
CConnman::NumConnections connections = CConnman::CONNECTIONS_NONE;
|
||||||
if (flags == CONNECTIONS_ALL) // Shortcut if we want total
|
|
||||||
return vNodes.size();
|
|
||||||
|
|
||||||
int nNum = 0;
|
if(flags == CONNECTIONS_IN)
|
||||||
BOOST_FOREACH(const CNode* pnode, vNodes)
|
connections = CConnman::CONNECTIONS_IN;
|
||||||
if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT))
|
else if (flags == CONNECTIONS_OUT)
|
||||||
nNum++;
|
connections = CConnman::CONNECTIONS_OUT;
|
||||||
|
else if (flags == CONNECTIONS_ALL)
|
||||||
|
connections = CConnman::CONNECTIONS_ALL;
|
||||||
|
|
||||||
return nNum;
|
if(g_connman)
|
||||||
|
return g_connman->GetNodeCount(connections);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ClientModel::getNumBlocks() const
|
int ClientModel::getNumBlocks() const
|
||||||
|
|
|
@ -54,24 +54,21 @@ public:
|
||||||
void refreshPeers()
|
void refreshPeers()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
TRY_LOCK(cs_vNodes, lockNodes);
|
|
||||||
if (!lockNodes)
|
|
||||||
{
|
|
||||||
// skip the refresh if we can't immediately get the lock
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cachedNodeStats.clear();
|
cachedNodeStats.clear();
|
||||||
|
std::vector<CNodeStats> vstats;
|
||||||
|
if(g_connman)
|
||||||
|
g_connman->GetNodeStats(vstats);
|
||||||
#if QT_VERSION >= 0x040700
|
#if QT_VERSION >= 0x040700
|
||||||
cachedNodeStats.reserve(vNodes.size());
|
cachedNodeStats.reserve(vstats.size());
|
||||||
#endif
|
#endif
|
||||||
Q_FOREACH (CNode* pnode, vNodes)
|
Q_FOREACH (const CNodeStats& nodestats, vstats)
|
||||||
{
|
{
|
||||||
CNodeCombinedStats stats;
|
CNodeCombinedStats stats;
|
||||||
stats.nodeStateStats.nMisbehavior = 0;
|
stats.nodeStateStats.nMisbehavior = 0;
|
||||||
stats.nodeStateStats.nSyncHeight = -1;
|
stats.nodeStateStats.nSyncHeight = -1;
|
||||||
stats.nodeStateStats.nCommonHeight = -1;
|
stats.nodeStateStats.nCommonHeight = -1;
|
||||||
stats.fNodeStateStatsAvailable = false;
|
stats.fNodeStateStatsAvailable = false;
|
||||||
pnode->copyStats(stats.nodeStats);
|
stats.nodeStats = nodestats;
|
||||||
cachedNodeStats.append(stats);
|
cachedNodeStats.append(stats);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -876,14 +876,14 @@ void RPCConsole::showBanTableContextMenu(const QPoint& point)
|
||||||
|
|
||||||
void RPCConsole::disconnectSelectedNode()
|
void RPCConsole::disconnectSelectedNode()
|
||||||
{
|
{
|
||||||
|
if(!g_connman)
|
||||||
|
return;
|
||||||
// Get currently selected peer address
|
// Get currently selected peer address
|
||||||
QString strNode = GUIUtil::getEntryData(ui->peerWidget, 0, PeerTableModel::Address).toString();
|
NodeId id = GUIUtil::getEntryData(ui->peerWidget, 0, PeerTableModel::NetNodeId).toInt();
|
||||||
// Find the node, disconnect it and clear the selected node
|
// Find the node, disconnect it and clear the selected node
|
||||||
if (CNode *bannedNode = FindNode(strNode.toStdString())) {
|
if(g_connman->DisconnectNode(id))
|
||||||
bannedNode->fDisconnect = true;
|
|
||||||
clearSelectedNode();
|
clearSelectedNode();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void RPCConsole::banSelectedNode(int bantime)
|
void RPCConsole::banSelectedNode(int bantime)
|
||||||
{
|
{
|
||||||
|
|
|
@ -457,7 +457,10 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
|
||||||
if (strMode != "template")
|
if (strMode != "template")
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
|
||||||
|
|
||||||
if (vNodes.empty())
|
if(!g_connman)
|
||||||
|
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
||||||
|
|
||||||
|
if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0)
|
||||||
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
|
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
|
||||||
|
|
||||||
if (IsInitialBlockDownload())
|
if (IsInitialBlockDownload())
|
||||||
|
|
|
@ -89,7 +89,8 @@ UniValue getinfo(const UniValue& params, bool fHelp)
|
||||||
#endif
|
#endif
|
||||||
obj.push_back(Pair("blocks", (int)chainActive.Height()));
|
obj.push_back(Pair("blocks", (int)chainActive.Height()));
|
||||||
obj.push_back(Pair("timeoffset", GetTimeOffset()));
|
obj.push_back(Pair("timeoffset", GetTimeOffset()));
|
||||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
if(g_connman)
|
||||||
|
obj.push_back(Pair("connections", (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL)));
|
||||||
obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
|
obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
|
||||||
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
||||||
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
|
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
|
||||||
|
|
|
@ -36,9 +36,10 @@ UniValue getconnectioncount(const UniValue& params, bool fHelp)
|
||||||
+ HelpExampleRpc("getconnectioncount", "")
|
+ HelpExampleRpc("getconnectioncount", "")
|
||||||
);
|
);
|
||||||
|
|
||||||
LOCK2(cs_main, cs_vNodes);
|
if(!g_connman)
|
||||||
|
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
||||||
|
|
||||||
return (int)vNodes.size();
|
return (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue ping(const UniValue& params, bool fHelp)
|
UniValue ping(const UniValue& params, bool fHelp)
|
||||||
|
@ -64,19 +65,6 @@ UniValue ping(const UniValue& params, bool fHelp)
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CopyNodeStats(std::vector<CNodeStats>& vstats)
|
|
||||||
{
|
|
||||||
vstats.clear();
|
|
||||||
|
|
||||||
LOCK(cs_vNodes);
|
|
||||||
vstats.reserve(vNodes.size());
|
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
|
||||||
CNodeStats stats;
|
|
||||||
pnode->copyStats(stats);
|
|
||||||
vstats.push_back(stats);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UniValue getpeerinfo(const UniValue& params, bool fHelp)
|
UniValue getpeerinfo(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() != 0)
|
if (fHelp || params.size() != 0)
|
||||||
|
@ -127,10 +115,11 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
|
||||||
+ HelpExampleRpc("getpeerinfo", "")
|
+ HelpExampleRpc("getpeerinfo", "")
|
||||||
);
|
);
|
||||||
|
|
||||||
LOCK(cs_main);
|
if(!g_connman)
|
||||||
|
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
||||||
|
|
||||||
vector<CNodeStats> vstats;
|
vector<CNodeStats> vstats;
|
||||||
CopyNodeStats(vstats);
|
g_connman->GetNodeStats(vstats);
|
||||||
|
|
||||||
UniValue ret(UniValue::VARR);
|
UniValue ret(UniValue::VARR);
|
||||||
|
|
||||||
|
@ -253,11 +242,12 @@ UniValue disconnectnode(const UniValue& params, bool fHelp)
|
||||||
+ HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"")
|
+ HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"")
|
||||||
);
|
);
|
||||||
|
|
||||||
CNode* pNode = FindNode(params[0].get_str());
|
if(!g_connman)
|
||||||
if (pNode == NULL)
|
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
||||||
throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
|
|
||||||
|
|
||||||
pNode->fDisconnect = true;
|
bool ret = g_connman->DisconnectNode(params[0].get_str());
|
||||||
|
if (!ret)
|
||||||
|
throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
|
||||||
|
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
}
|
}
|
||||||
|
@ -435,7 +425,6 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp)
|
||||||
);
|
);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
||||||
UniValue obj(UniValue::VOBJ);
|
UniValue obj(UniValue::VOBJ);
|
||||||
obj.push_back(Pair("version", CLIENT_VERSION));
|
obj.push_back(Pair("version", CLIENT_VERSION));
|
||||||
obj.push_back(Pair("subversion", strSubVersion));
|
obj.push_back(Pair("subversion", strSubVersion));
|
||||||
|
@ -443,7 +432,8 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp)
|
||||||
obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
|
obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
|
||||||
obj.push_back(Pair("localrelay", fRelayTxes));
|
obj.push_back(Pair("localrelay", fRelayTxes));
|
||||||
obj.push_back(Pair("timeoffset", GetTimeOffset()));
|
obj.push_back(Pair("timeoffset", GetTimeOffset()));
|
||||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
if(g_connman)
|
||||||
|
obj.push_back(Pair("connections", (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL)));
|
||||||
obj.push_back(Pair("networks", GetNetworksInfo()));
|
obj.push_back(Pair("networks", GetNetworksInfo()));
|
||||||
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
|
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
|
||||||
UniValue localAddresses(UniValue::VARR);
|
UniValue localAddresses(UniValue::VARR);
|
||||||
|
|
Loading…
Reference in a new issue