Skip to content

Commit

Permalink
expose dynamic memory with RPC
Browse files Browse the repository at this point in the history
  • Loading branch information
amitiuttarwar committed Oct 11, 2023
1 parent 5ee0328 commit 29bc5c1
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 30 deletions.
14 changes: 13 additions & 1 deletion src/memusage.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <vector>
#include <unordered_map>
#include <unordered_set>

#include <deque>

namespace memusage
{
Expand Down Expand Up @@ -90,6 +90,18 @@ static inline size_t DynamicUsage(const std::vector<X>& v)
return MallocUsage(v.capacity() * sizeof(X));
}

template<typename X>
static inline size_t DynamicUsage(const std::list<X>& v)
{
return MallocUsage(v.size() * sizeof(X));
}

template<typename X>
static inline size_t DynamicUsage(const std::deque<X>& v)
{
return MallocUsage(v.size() * sizeof(X));
}

template<unsigned int N, typename X, typename S, typename D>
static inline size_t DynamicUsage(const prevector<N, X, S, D>& v)
{
Expand Down
31 changes: 23 additions & 8 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,25 @@ std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(g_maplocalhost_mute
static bool vfLimited[NET_MAX] GUARDED_BY(g_maplocalhost_mutex) = {};
std::string strSubVersion;

// returning approx 4000 - 5000
size_t CNode::DynamicMemoryUsage() const {
size_t val = 0;

val += memusage::DynamicUsage(m_transport);
//LOCK(m_sock_mutex);
//LOCK(cs_vSend);
//LOCK(m_msg_process_queue_mutex);
//LOCK(cs_vRecv);

// m_transport is going to be assigned dynamically as V1Transport or V2Transport
//WITH_LOCK(cs_vSend, val += m_send_memusage); //tracks the memory usage of all vSendMsg entries -> send buffer
// vRecvMsg
// m_msg_process_queue -> m_msg_process_queue_size
// mapSendBytesPerMsgType
// mapRecvBytesPerMsgType
// m_i2p_sam_session
val += memusage::DynamicUsage(m_transport);
val += memusage::DynamicUsage(m_sock);
val += m_send_memusage; // should represent memory usage of vSendMsg
auto calc_val = memusage::DynamicUsage(vSendMsg);
LogPrintf("ABCD m_send_memusage: %d, calculated value of vSendMsg %d\n", m_send_memusage, calc_val);
val += memusage::DynamicUsage(vRecvMsg);
val += memusage::DynamicUsage(m_msg_process_queue);
val += memusage::DynamicUsage(mapSendBytesPerMsgType);
val += memusage::DynamicUsage(mapRecvBytesPerMsgType);
val += memusage::DynamicUsage(m_i2p_sam_session);

return val;
}
Expand Down Expand Up @@ -3591,6 +3598,14 @@ uint32_t CConnman::GetMappedAS(const CNetAddr& addr) const
return m_netgroupman.GetMappedAS(addr);
}

void CConnman::GetNodeMemory(std::map<NodeId, size_t>& info) const
{
LOCK(m_nodes_mutex);
for (CNode* pnode : m_nodes) {
info[pnode->GetId()] = pnode->DynamicMemoryUsage();
}
}

void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats) const
{
vstats.clear();
Expand Down
1 change: 1 addition & 0 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,7 @@ class CConnman
size_t GetNodeCount(ConnectionDirection) const;
uint32_t GetMappedAS(const CNetAddr& addr) const;
void GetNodeStats(std::vector<CNodeStats>& vstats) const;
void GetNodeMemory(std::map<NodeId, size_t>& info) const;
bool DisconnectNode(const std::string& node);
bool DisconnectNode(const CSubNet& subnet);
bool DisconnectNode(const CNetAddr& addr);
Expand Down
43 changes: 22 additions & 21 deletions src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,8 @@ static RPCHelpMan getpeermemoryinfo()
{RPCResult::Type::OBJ, "", "",
{
{
{RPCResult::Type::NUM, "id", "Peer index"},
{RPCResult::Type::STR, "addr", "(host:port) The IP address and port of the peer"},
{RPCResult::Type::BOOL, "addr_relay_enabled", "Whether we participate in address relay with this peer"},
{RPCResult::Type::NUM, "id", "Peer id"},
{RPCResult::Type::NUM, "memory", "the result of GetDynamicMemoryUsage for that node"},
}},
}},
},
Expand All @@ -124,29 +123,31 @@ static RPCHelpMan getpeermemoryinfo()
{
NodeContext& node = EnsureAnyNodeContext(request.context);
const CConnman& connman = EnsureConnman(node);
const PeerManager& peerman = EnsurePeerman(node);
//const PeerManager& peerman = EnsurePeerman(node);

std::vector<CNodeStats> vstats;
connman.GetNodeStats(vstats);
//std::vector<CNodeStats> vstats;
//connman.GetNodeStats(vstats);

// map of node id -> memory usage
std::map<int64_t, size_t> info;
connman.GetNodeMemory(info);

UniValue ret(UniValue::VARR);

for (const CNodeStats& stats : vstats) {
UniValue obj(UniValue::VOBJ);
CNodeStateStats statestats;
bool fStateStats = peerman.GetNodeStateStats(stats.nodeid, statestats);
// GetNodeStateStats() requires the existence of a CNodeState and a Peer object
// to succeed for this peer. These are created at connection initialisation and
// exist for the duration of the connection - except if there is a race where the
// peer got disconnected in between the GetNodeStats() and the GetNodeStateStats()
// calls. In this case, the peer doesn't need to be reported here.
if (!fStateStats) {
continue;
}
obj.pushKV("id", stats.nodeid);
obj.pushKV("addr", stats.m_addr_name);
obj.pushKV("addr_relay_enabled", statestats.m_addr_relay_enabled);
//for (const CNodeStats& stats : vstats) {
//UniValue obj(UniValue::VOBJ);
//CNodeStateStats statestats;
//obj.pushKV("id", stats.nodeid);
//obj.pushKV("addr", stats.m_addr_name);
//obj.pushKV("addr_relay_enabled", statestats.m_addr_relay_enabled);

//ret.push_back(obj);
//}

for (const auto& vals : info) {
UniValue obj(UniValue::VOBJ);
obj.pushKV("id", vals.first);
obj.pushKV("memory", vals.second);
ret.push_back(obj);
}

Expand Down

0 comments on commit 29bc5c1

Please sign in to comment.