rpc: add ‘getnetmsgstats’, new rpc to view network message statistics #27534

pull satsie wants to merge 9 commits into bitcoin:master from satsie:2023-03-getnetmsgstats changing 12 files +779 −11
  1. satsie commented at 8:21 pm on April 26, 2023: contributor

    Introduce a new RPC, getnetmsgstats to retrieve network message statistics. This work addresses #26337. More information on the RPC design and implementation can be found in that issue.

    Massive thank-you to amitiuttarwar, vasild, and ajtowns for their help on this :pray: Over the course of several months, they have patiently provided a tremendous amount of guidance and assistance in more ways than I can count!


    getnetmsgstats RPC

    Returns the message count and total number of bytes for sent and received network traffic. Results may optionally be arranged by direction, network, connection type and/or message type.

    Arguments

    show_only: an optional array of one or more dimensions to show as part of the results. Valid options are: direction, network, message_type, and connection_type. If no dimensions are specified, totals are returned.

    Examples

    Below are some examples on how the new getnetmsgstats RPC can be used.

    0 ./src/bitcoin-cli getnetmsgstats
    1{
    2  "totals": {
    3    "message_count": 1905,
    4    "byte_count": 818941962
    5  }
    6}
    
      0./src/bitcoin-cli getnetmsgstats '["conntype","msgtype"]'
      1{
      2  "block-relay-only": {
      3    "addrv2": {
      4      "message_count": 1,
      5      "byte_count": 40
      6    },
      7    "block": {
      8      "message_count": 6,
      9      "byte_count": 9899426
     10    },
     11    "cmpctblock": {
     12      "message_count": 1,
     13      "byte_count": 16615
     14    },
     15    "feefilter": {
     16      "message_count": 1,
     17      "byte_count": 32
     18    },
     19    "getdata": {
     20      "message_count": 1,
     21      "byte_count": 241
     22    },
     23    "getheaders": {
     24      "message_count": 4,
     25      "byte_count": 4212
     26    },
     27    "headers": {
     28      "message_count": 10,
     29      "byte_count": 1303
     30    },
     31    "inv": {
     32      "message_count": 6,
     33      "byte_count": 366
     34    },
     35    "ping": {
     36      "message_count": 4,
     37      "byte_count": 128
     38    },
     39    "pong": {
     40      "message_count": 4,
     41      "byte_count": 128
     42    },
     43    "sendaddrv2": {
     44      "message_count": 4,
     45      "byte_count": 96
     46    },
     47    "sendcmpct": {
     48      "message_count": 6,
     49      "byte_count": 198
     50    },
     51    "sendheaders": {
     52      "message_count": 4,
     53      "byte_count": 96
     54    },
     55    "verack": {
     56      "message_count": 4,
     57      "byte_count": 96
     58    },
     59    "version": {
     60      "message_count": 4,
     61      "byte_count": 507
     62    },
     63    "wtxidrelay": {
     64      "message_count": 4,
     65      "byte_count": 96
     66    }
     67  },
     68  "outbound-full-relay": {
     69    "addr": {
     70      "message_count": 6,
     71      "byte_count": 30302
     72    },
     73    "addrv2": {
     74      "message_count": 10,
     75      "byte_count": 76016
     76    },
     77    "blocktxn": {
     78      "message_count": 1,
     79      "byte_count": 1288086
     80    },
     81    "cmpctblock": {
     82      "message_count": 1,
     83      "byte_count": 16615
     84    },
     85    "feefilter": {
     86      "message_count": 15,
     87      "byte_count": 480
     88    },
     89    "getaddr": {
     90      "message_count": 8,
     91      "byte_count": 192
     92    },
     93    "getblocktxn": {
     94      "message_count": 1,
     95      "byte_count": 2515
     96    },
     97    "getdata": {
     98      "message_count": 79,
     99      "byte_count": 16951
    100    },
    101    "getheaders": {
    102      "message_count": 15,
    103      "byte_count": 15795
    104    },
    105    "headers": {
    106      "message_count": 20,
    107      "byte_count": 2039
    108    },
    109    "inv": {
    110      "message_count": 134,
    111      "byte_count": 58826
    112    },
    113    "notfound": {
    114      "message_count": 7,
    115      "byte_count": 787
    116    },
    117    "other": {
    118      "message_count": 6,
    119      "byte_count": 438
    120    },
    121    "ping": {
    122      "message_count": 15,
    123      "byte_count": 480
    124    },
    125    "pong": {
    126      "message_count": 14,
    127      "byte_count": 448
    128    },
    129    "sendaddrv2": {
    130      "message_count": 10,
    131      "byte_count": 240
    132    },
    133    "sendcmpct": {
    134      "message_count": 19,
    135      "byte_count": 627
    136    },
    137    "sendheaders": {
    138      "message_count": 14,
    139      "byte_count": 336
    140    },
    141    "tx": {
    142      "message_count": 398,
    143      "byte_count": 211333
    144    },
    145    "verack": {
    146      "message_count": 16,
    147      "byte_count": 384
    148    },
    149    "version": {
    150      "message_count": 17,
    151      "byte_count": 2151
    152    },
    153    "wtxidrelay": {
    154      "message_count": 10,
    155      "byte_count": 240
    156    }
    157  }
    158}
    
      0./src/bitcoin-cli getnetmsgstats '["network", "direction", "connection_type", "message_type"]'
      1{
      2  "ipv4": {
      3    "received": {
      4      "block-relay-only": {
      5        "addrv2": {
      6          "message_count": 5,
      7          "byte_count": 227
      8        },
      9        "block": {
     10          "message_count": 6,
     11          "byte_count": 9899426
     12        },
     13        "cmpctblock": {
     14          "message_count": 2,
     15          "byte_count": 25184
     16        },
     17        "feefilter": {
     18          "message_count": 1,
     19          "byte_count": 32
     20        },
     21        "getheaders": {
     22          "message_count": 2,
     23          "byte_count": 2106
     24        },
     25        "headers": {
     26          "message_count": 6,
     27          "byte_count": 1041
     28        },
     29        "inv": {
     30          "message_count": 3,
     31          "byte_count": 183
     32        },
     33        "ping": {
     34          "message_count": 6,
     35          "byte_count": 192
     36        },
     37        "pong": {
     38          "message_count": 6,
     39          "byte_count": 192
     40        },
     41        "sendaddrv2": {
     42          "message_count": 2,
     43          "byte_count": 48
     44        },
     45        "sendcmpct": {
     46          "message_count": 3,
     47          "byte_count": 99
     48        },
     49        "sendheaders": {
     50          "message_count": 2,
     51          "byte_count": 48
     52        },
     53        "verack": {
     54          "message_count": 2,
     55          "byte_count": 48
     56        },
     57        "version": {
     58          "message_count": 2,
     59          "byte_count": 253
     60        },
     61        "wtxidrelay": {
     62          "message_count": 2,
     63          "byte_count": 48
     64        }
     65      },
     66      "outbound-full-relay": {
     67        "addr": {
     68          "message_count": 4,
     69          "byte_count": 30222
     70        },
     71        "addrv2": {
     72          "message_count": 26,
     73          "byte_count": 148422
     74        },
     75        "blocktxn": {
     76          "message_count": 2,
     77          "byte_count": 3752987
     78        },
     79        "cmpctblock": {
     80          "message_count": 2,
     81          "byte_count": 25184
     82        },
     83        "feefilter": {
     84          "message_count": 11,
     85          "byte_count": 352
     86        },
     87        "getdata": {
     88          "message_count": 24,
     89          "byte_count": 2184
     90        },
     91        "getheaders": {
     92          "message_count": 11,
     93          "byte_count": 11583
     94        },
     95        "headers": {
     96          "message_count": 20,
     97          "byte_count": 2120
     98        },
     99        "inv": {
    100          "message_count": 275,
    101          "byte_count": 116207
    102        },
    103        "notfound": {
    104          "message_count": 9,
    105          "byte_count": 981
    106        },
    107        "other": {
    108          "message_count": 44,
    109          "byte_count": 3430
    110        },
    111        "ping": {
    112          "message_count": 20,
    113          "byte_count": 640
    114        },
    115        "pong": {
    116          "message_count": 20,
    117          "byte_count": 640
    118        },
    119        "sendaddrv2": {
    120          "message_count": 9,
    121          "byte_count": 216
    122        },
    123        "sendcmpct": {
    124          "message_count": 18,
    125          "byte_count": 594
    126        },
    127        "sendheaders": {
    128          "message_count": 11,
    129          "byte_count": 264
    130        },
    131        "tx": {
    132          "message_count": 1161,
    133          "byte_count": 596142
    134        },
    135        "verack": {
    136          "message_count": 12,
    137          "byte_count": 288
    138        },
    139        "version": {
    140          "message_count": 12,
    141          "byte_count": 1536
    142        },
    143        "wtxidrelay": {
    144          "message_count": 9,
    145          "byte_count": 216
    146        }
    147      }
    148    },
    149    "sent": {
    150      "block-relay-only": {
    151        "getdata": {
    152          "message_count": 1,
    153          "byte_count": 241
    154        },
    155        "getheaders": {
    156          "message_count": 2,
    157          "byte_count": 2106
    158        },
    159        "headers": {
    160          "message_count": 6,
    161          "byte_count": 474
    162        },
    163        "inv": {
    164          "message_count": 3,
    165          "byte_count": 183
    166        },
    167        "ping": {
    168          "message_count": 6,
    169          "byte_count": 192
    170        },
    171        "pong": {
    172          "message_count": 6,
    173          "byte_count": 192
    174        },
    175        "sendaddrv2": {
    176          "message_count": 2,
    177          "byte_count": 48
    178        },
    179        "sendcmpct": {
    180          "message_count": 3,
    181          "byte_count": 99
    182        },
    183        "sendheaders": {
    184          "message_count": 2,
    185          "byte_count": 48
    186        },
    187        "verack": {
    188          "message_count": 2,
    189          "byte_count": 48
    190        },
    191        "version": {
    192          "message_count": 2,
    193          "byte_count": 254
    194        },
    195        "wtxidrelay": {
    196          "message_count": 2,
    197          "byte_count": 48
    198        }
    199      },
    200      "outbound-full-relay": {
    201        "addr": {
    202          "message_count": 4,
    203          "byte_count": 250
    204        },
    205        "addrv2": {
    206          "message_count": 19,
    207          "byte_count": 938
    208        },
    209        "feefilter": {
    210          "message_count": 12,
    211          "byte_count": 384
    212        },
    213        "getaddr": {
    214          "message_count": 12,
    215          "byte_count": 288
    216        },
    217        "getblocktxn": {
    218          "message_count": 2,
    219          "byte_count": 3883
    220        },
    221        "getdata": {
    222          "message_count": 249,
    223          "byte_count": 48813
    224        },
    225        "getheaders": {
    226          "message_count": 12,
    227          "byte_count": 12636
    228        },
    229        "headers": {
    230          "message_count": 13,
    231          "byte_count": 1297
    232        },
    233        "inv": {
    234          "message_count": 464,
    235          "byte_count": 166868
    236        },
    237        "ping": {
    238          "message_count": 21,
    239          "byte_count": 672
    240        },
    241        "pong": {
    242          "message_count": 20,
    243          "byte_count": 640
    244        },
    245        "sendaddrv2": {
    246          "message_count": 9,
    247          "byte_count": 216
    248        },
    249        "sendcmpct": {
    250          "message_count": 13,
    251          "byte_count": 429
    252        },
    253        "sendheaders": {
    254          "message_count": 11,
    255          "byte_count": 264
    256        },
    257        "tx": {
    258          "message_count": 44,
    259          "byte_count": 18966
    260        },
    261        "verack": {
    262          "message_count": 12,
    263          "byte_count": 288
    264        },
    265        "version": {
    266          "message_count": 13,
    267          "byte_count": 1651
    268        },
    269        "wtxidrelay": {
    270          "message_count": 9,
    271          "byte_count": 216
    272        }
    273      }
    274    }
    275  }
    276}
    

    Things to consider

    RPC behavior: Should we allow dimensions to be rearraged?

    When it comes time to gather up the RPC results, @vasild has provided an alternate implementation that uses an array instead of the MultiMap structure. This results in two changes:

    • using the stack over the heap (yay!)
    • enforcing a strict ordering of dimensions (direction, network, connection type, message type)

    Aside from being good for memory, the reasoning here is allowing users to rearrange dimensions may be too confusing. I personally really like the ability to rearrange dimensions, which is why I have not integrated that solution into this PR, but am open to whatever the larger community prefers :)

    Locking & Consistency Beyond Individual Values

    With atomics, we know we can rely on the values for individual stats like bye count and message count. However, the byte count and message count may not always match. For example, let’s say we currently have 5 messages, and 100 bytes:

    1. A new 20 byte message comes in. First the byte count is incremented to 120.
    2. A request to read the stats comes in. The RPC returns message count 5 and byte count 120.
    3. The message count is incremented to 6 in response to the new message that came in at step 1.
    

    The read operation did not return accurate data! Unlike the torn write example for a single value, It returned data that was true for some point in time, it’s just that the values for message count and byte count were inconsistent.

    To solve this, it’s actually not enough to lock the MsgStat struct. It’s my understanding that you need a mutex to protect the entire NetStats data structure.

    The trade off here isn’t attractive. A lock would halt network threads that are doing important stuff, all for the sake of consistent stats. Even for reads, we would have to stop writes. We’d end up stopping threads that are doing important things for something that is not that important.

    Another thing to consider is how often will this RPC be called? If it’s once in a blue moon, then such a mutex is probably fine. But for a live dashboard that is making a call every second, this is not acceptable.

    Making Enum Indices Safe and Reliable

    src/net.cpp contains a bunch of *To/FromIndex() methods that convert an enum to an index number. I’ve decided to be explicit about these conversions because enums are not guaranteed to start at zero and it’s not enough to simply associate the first value in an enum with a number.

    To protect against potential gaps or overlaps in numbering, every single enum value must be assigned an index. This is the only way to guarantee that the numbering is safe and reliable.

    Instead of updating the existing Network and ConnectionType enums to assign indices to each enum value, and risk unintentionally modifying the behavior of code that uses these enums, I’ve opted for the conversion methods. This also narrows the scope of the conversion methods, making changed behavior easier to spot if the indices are modified.

    I’m interested in feedback on this. The *To/FromIndex() methods have low review and maintenance cost, but I’m unsure if I’ve correctly evaluated the risks associated with updating the Network and ConnectionType enums . Also open to discussion on if there is a better place for these conversion methods to live.

  2. DrahtBot commented at 8:21 pm on April 26, 2023: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    Concept ACK ccdle12, amitiuttarwar

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #28066 (fuzz: Generate process_message targets individually by MarcoFalke)
    • #27770 (Introduce ‘getblockfileinfo’ RPC command by furszy)
    • #27407 (net, refactor: Privatise CNode send queue by dergoegge)
    • #27385 (net, refactor: extract Network and BIP155Network logic to node/network by jonatack)
    • #27213 (p2p: Diversify automatic outbound connections with respect to networks by amitiuttarwar)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  3. DrahtBot added the label RPC/REST/ZMQ on Apr 26, 2023
  4. satsie marked this as a draft on Apr 26, 2023
  5. DrahtBot added the label CI failed on Apr 26, 2023
  6. satsie force-pushed on Apr 27, 2023
  7. satsie force-pushed on Apr 27, 2023
  8. satsie force-pushed on Apr 27, 2023
  9. DrahtBot removed the label CI failed on Apr 27, 2023
  10. satsie marked this as ready for review on Apr 27, 2023
  11. in src/net.h:427 in 210cf10227 outdated
    499@@ -421,8 +500,10 @@ class CNode
    500 
    501     const ConnectionType m_conn_type;
    502 
    503-    /** Move all messages from the received queue to the processing queue. */
    504-    void MarkReceivedMsgsForProcessing()
    505+    /** Move all messages from the received queue to the processing queue.
    506+     * Also update the global map of network message statistics.
    507+     */
    508+    void MarkReceivedMsgsForProcessing(NetStats& net_stats)
    


    satsie commented at 5:42 pm on April 27, 2023:

    Would it be better to pass a reference of NetStats to every CNode upon initialization?

    Example: https://github.com/bitcoin/bitcoin/commit/cd0c8eeb0940790b6ba83786d1c9e362d4dc4829


    ccdle12 commented at 3:12 pm on May 2, 2023:
    According to this review comment: #27257 (review) - It looks like it would be preferable for CNode to have net_stats as a member variable (I could be wrong) but that might mean each CNode would need to have a shared_ptr to a NetStats instance.

    satsie commented at 8:25 pm on May 10, 2023:
    This is a great point. I think I need to take a closer look at some of the refactoring that’s going on in net in hopes of finding other examples/decisions that support making NetStats a member variable in CNode. I think the comment you linked to is very relevant.
  12. in src/net.cpp:2839 in 210cf10227 outdated
    2935@@ -2828,6 +2936,12 @@ void CNode::MarkReceivedMsgsForProcessing()
    2936         // vRecvMsg contains only completed CNetMessage
    2937         // the single possible partially deserialized message are held by TransportDeserializer
    2938         nSizeAdded += msg.m_raw_message_size;
    2939+
    2940+        net_stats.Record(NetStats::Direction::RECV,
    2941+                         ConnectedThroughNetwork(),
    2942+                         m_conn_type,
    2943+                         msg.m_type,
    2944+                         msg.m_raw_message_size);
    


    satsie commented at 5:51 pm on April 27, 2023:

    Now that an effort has been made to remove the friendship between CConnman and CNode (see this PR: #27257) I’m unsure if this (recording network stats on a CConnman object) belongs here.

    Also related, is an open PR that would similarly impact the recording of sent stats: https://github.com/bitcoin/bitcoin/pull/27407


    amitiuttarwar commented at 0:37 am on May 12, 2023:
  13. in src/protocol.cpp:52 in 210cf10227 outdated
    48@@ -49,6 +49,8 @@ const char *WTXIDRELAY="wtxidrelay";
    49 const char *SENDTXRCNCL="sendtxrcncl";
    50 } // namespace NetMsgType
    51 
    52+const std::string NET_MESSAGE_TYPE_OTHER = "*other*";
    


    satsie commented at 5:52 pm on April 27, 2023:
    This was moved over from net.cpp. Should it be in the NetMsgType namespace? If so, what about the allNetMessageTypes array? There are places in this PR where I have to add +1 to account for the missing ‘other’ message type, and I’m not sure if it’s appropriate for this to be a special case.

    amitiuttarwar commented at 0:50 am on May 12, 2023:

    adding it to the NetMsgType namespace makes sense to me- the current name essentially manually namespaces it.

    RE allNetMessageTypes array - either way seems OK to me. from a quick glance at callers, I don’t think you’d have to add much special case logic if you added it in the array, so that could be nice

  14. in src/net.h:352 in 210cf10227 outdated
    343@@ -345,6 +344,86 @@ class V1TransportSerializer : public TransportSerializer {
    344     void prepareForTransport(CSerializedNetMsg& msg, std::vector<unsigned char>& header) const override;
    345 };
    346 
    347+/**
    348+ * Placeholder for total network traffic. Split by direction, network, connection
    349+ * type and message type (byte and message counts).
    350+ */
    351+class NetStats
    


    jonatack commented at 6:16 pm on April 27, 2023:
    Would it be a good idea for this class to be in its own file/compilation unit, rather than added into net.h (which is included in 40+ other files)?

    amitiuttarwar commented at 0:45 am on May 12, 2023:
    +1 I think having this code in a separate compilation unit + forward declaration of the class would be sufficient for net.h, then net.cpp could include the full file

    satsie commented at 5:22 pm on June 2, 2023:
    Sounds good! Will work on this now (leaving this reply in case this comment disappears once I rebase)
  15. in src/net.h:416 in 210cf10227 outdated
    411+    // assuming MessageTypeToIndex("ping") == 15, then everything stored in
    412+    // m_data[x][y][z][15] is traffic from "ping" messages (for any x, y or z).
    413+
    414+    static Direction DirectionFromIndex(size_t index);
    415+    static Network NetworkFromIndex(size_t index);
    416+    static ConnectionType ConnectionTypeFromIndex(size_t index);
    


    jonatack commented at 6:23 pm on April 27, 2023:

    Not sure if these to/from util helper methods are needed or if this is the right place for them rather than in their respective domains where available, like node/connection_type and node/network (the latter proposed in #27385).

    Unrelated, can also make the declaration of new methods that return a value [[nodiscard]].


    satsie commented at 6:40 pm on May 1, 2023:

    I agree with the questioning of where these util methods belong.

    I didn’t know about [[nodiscard]]. Cool feature! Added it to the public *(to/from)Index and private *ToIndex methods by this comment. New commit after update + rebase: https://github.com/bitcoin/bitcoin/pull/27534/commits/fc86267b0ece8d31915a4869741f4602622f2bcb

    I may end up adding it to more stuff as I work through the code, but did not do a full sweep of additional areas where it could be applied.

  16. in src/rpc/net.cpp:515 in 210cf10227 outdated
    510@@ -509,6 +511,396 @@ static RPCHelpMan getaddednodeinfo()
    511     };
    512 }
    513 
    514+namespace net_stats {
    


    jonatack commented at 6:25 pm on April 27, 2023:
    Perhaps consider putting all this new code in its own rpc/netstats files.
  17. in src/protocol.h:278 in 210cf10227 outdated
    273+
    274 /* Get a vector of all valid message types (see above) */
    275 const std::vector<std::string>& getAllNetMessageTypes();
    276 
    277+/* Get the index of a message type from the vector of all message types */
    278+int messageTypeToIndex(std::string msg_type);
    



    satsie commented at 6:01 pm on May 1, 2023:
    Ooooo thank you! I never would have caught this. Fixed and rebased: https://github.com/bitcoin/bitcoin/pull/27534/commits/5ed0c78efd9e43bcb84d85c257081e224cf5e69f
  18. in src/node/connection_types.h:81 in 210cf10227 outdated
    76@@ -76,6 +77,9 @@ enum class ConnectionType {
    77     ADDR_FETCH,
    78 };
    79 
    80+/** Number of entries in ConnectionType. */
    81+static constexpr size_t NUM_CONNECTION_TYPES{6};
    


    jonatack commented at 6:41 pm on April 27, 2023:
    Perhaps better to calculate this programmatically, so it doesn’t need to be updated, as there are multiple pulls IIRC that propose to add more such types.

    satsie commented at 5:49 pm on May 1, 2023:

    Agree with the idea of programmatic calculation. I noticed NET_MAX in netaddress.h accomplishes this by adding an enum value to the end of the list. That new value serves as a counter for all the enums. I initially implemented these (number of connection and message types) in that same manner because it seemed more programmatic. As long as new enums were inserted before, then I figured they would be accounted for in the total.

    However, l Iater got feedback and the unreliability of mapping enums to integers was brought to my attention. Every single enum needs to be explicitly mapped to an integer, and if you’re going to go through the trouble of that, then it comes out to be basically the same amount of work to make a standalone constant. There’s also something that doesn’t feel consistent about having an enum that accounts for the total living alongside the enum values that are being counted.

    In this PR I have a static assert checking that NUM_NET_MESSAGE_TYPES is what we expect it to be. Would love if there was somehow a way to do that with the number of connection types as well. It’s not exactly setting the value in a programmatic way, but it’s at least providing some kind of check.

    From src/protocol.cpp:

    0static_assert(NUM_NET_MESSAGE_TYPES == sizeof(allNetMessageTypes) / sizeof(allNetMessageTypes[0]), "Please update NUM_NET_MESSAGE_TYPES");
    

    amitiuttarwar commented at 0:07 am on May 12, 2023:
    @satsie is the concern of having a dummy value like NET_MAX that it could fall out of sync if enum values start being explicitly assigned?

    satsie commented at 5:17 pm on June 2, 2023:

    @amitiuttarwar sort of. It’s two things:

    1. If enum values are not explicitly assigned (which is the case for the Network enum right now), there is no guarantee that NET_MAX is what you think it will be. This came out of a conversation with @vasild during review earlier this year. It’s my understanding that NET_MAX probably corresponds to the total number of enum values, but even today there are no guarantees on the value of NET_MAX. I’d like to do a little more research here and get some clear documentation on this though, as I’m currently just going off of information that was given to me.

    2. If you start explicitly assigning integers to each enum value, you still have to update NET_MAX, so I don’t think it is in that much danger of falling out of sync, but it is the same amount of work as updating a constant like NUM_CONNECTION_TYPES here.

  19. jonatack commented at 6:52 pm on April 27, 2023: contributor
    A few initial thoughts, mainly about code organization.
  20. satsie force-pushed on May 1, 2023
  21. satsie force-pushed on May 1, 2023
  22. satsie commented at 6:45 pm on May 1, 2023: contributor
    Thank you for taking a look @jonatack! :pray: All your comments on code organization are fair game and something I’ve wondered myself. Because I have absolutely zero point of reference for any of this, I’m going to to leave your comments about organization open with the hopes of getting more feedback.
  23. in src/net.h:358 in 689a0cb0ad outdated
    353+public:
    354+    struct MsgStat {
    355+        std::atomic_uint64_t byte_count; //!< Number of bytes transferred.
    356+        std::atomic_uint64_t msg_count;  //!< Number of messages transferred.
    357+
    358+        MsgStat() : byte_count{0}, msg_count{0} {}
    


    ccdle12 commented at 3:11 pm on May 2, 2023:

    nit: This constructor could use the default keyword since byte_count and msg_count will default to 0.

    e.g. https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c80-use-default-if-you-have-to-be-explicit-about-using-the-default-semantics

    0 MsgStat() = default;
    

    satsie commented at 8:11 pm on May 10, 2023:

    Ooooo thank you! C++ rookie here :smile:

    Fixed in f5c8b5f78f93bea96e6846ef9d5b787269029b50

  24. ccdle12 commented at 3:14 pm on May 2, 2023: contributor
    Concept tACK - left a few very minor comments, happy to keep testing and reviewing in more depth
  25. DrahtBot added the label Needs rebase on May 9, 2023
  26. satsie force-pushed on May 10, 2023
  27. net: move NET_MESSAGE_TYPE_OTHER
    Move NET_MESSAGE_TYPE_OTHER to protocol.h/cpp, where the rest of the
    message types live.
    2f9bdcfc25
  28. net: make constants for total conn and msg types
    Add consts to keep track of the number of connection and message types.
    The number of message types should match the number of elements in the
    allNetMessageTypes array.
    
    Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
    61b15b53cf
  29. net: add methods to convert a message type to/from an index 050509cdb8
  30. satsie force-pushed on May 10, 2023
  31. satsie commented at 8:27 pm on May 10, 2023: contributor

    Thank you for testing and taking a peek at this @ccdle12 :hugs: Appreciate the review and will definitely be taking you up on the offer for a more in depth review as this evolves! :wink:

    EDIT: also wanted to mention I rebased. I’m guessing DrahtBot is going to remove the label? :eyes:

  32. DrahtBot added the label CI failed on May 10, 2023
  33. DrahtBot removed the label Needs rebase on May 10, 2023
  34. DrahtBot removed the label CI failed on May 11, 2023
  35. in src/protocol.cpp:207 in 050509cdb8 outdated
    202+        // assign the last index to be a catch all for NET_MESSAGE_TYPE_OTHER
    203+        return NUM_NET_MESSAGE_TYPES;
    204+    }
    205+}
    206+
    207+const std::string& messageTypeFromIndex(size_t index)
    


    amitiuttarwar commented at 0:14 am on May 12, 2023:
    this function should handle if index > NUM_NET_MESSAGE_TYPES

    satsie commented at 5:20 pm on June 2, 2023:

    Good point. Do you think it’s okay to do

    0    if (index >= NUM_NET_MESSAGE_TYPES) {
    1        return NET_MESSAGE_TYPE_OTHER;
    2    }
    

    Or should I add a separate case for if (index > NUM_NET_MESSAGE_TYPES) that throws an error? Not in love with this because it’s harder to get test coverage, but it certainly feels like the more correct thing to do.

  36. in src/net.h:377 in 219eaa87d6 outdated
    371+    using MultiDimensionalStats = std::array<std::array<std::array<std::array<MsgStat,
    372+                                                                                // add 1 for the other message type
    373+                                                                                NUM_NET_MESSAGE_TYPES + 1>,
    374+                                                                    NUM_CONNECTION_TYPES>,
    375+                                                        NET_MAX>,
    376+                                                NUM_DIRECTIONS>;
    


    amitiuttarwar commented at 0:27 am on May 12, 2023:
    nit: I’m kinda confused by this spacing. could it be a bit more legible to have them just line up instead of cascade?

    satsie commented at 6:09 pm on June 2, 2023:
    oof. some of the spacing is not quite right here even for cascading. I’m going to fix it in the new compilation unit/file, maybe then it will make a little more sense? I’m worried lining them up isn’t going to be much help. It’s hard to read too because the declaration for this 4D array happens by nesting arrays in arrays :sob:
  37. amitiuttarwar commented at 0:51 am on May 12, 2023: contributor
    approach ACK. did a high-level review and left a few small comments
  38. satsie force-pushed on Jun 2, 2023
  39. satsie force-pushed on Jun 2, 2023
  40. DrahtBot added the label CI failed on Jun 2, 2023
  41. satsie force-pushed on Jun 2, 2023
  42. satsie force-pushed on Jun 2, 2023
  43. satsie force-pushed on Jun 2, 2023
  44. satsie force-pushed on Jun 2, 2023
  45. satsie force-pushed on Jun 2, 2023
  46. satsie force-pushed on Jun 2, 2023
  47. satsie force-pushed on Jun 2, 2023
  48. satsie force-pushed on Jun 2, 2023
  49. satsie force-pushed on Jun 2, 2023
  50. satsie force-pushed on Jun 2, 2023
  51. satsie force-pushed on Jun 2, 2023
  52. satsie force-pushed on Jun 2, 2023
  53. satsie force-pushed on Jun 2, 2023
  54. net: create a data structure for network message stats
    New data structure to hold the atomic message and byte counts of each
    network message statistic at the most granular level. Uses a 4D array
    that indexes by direction, network type, connection type, and message
    type.
    
    Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
    1110e3176a
  55. net: add to/fromIndex() methods to NetStats
    Add to/fromIndex() methods to safely map enums to indexes.
    
    Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
    44902fe484
  56. net: count transferred bytes & messages globally
    In addition to per-peer stats, start recording stats (the number of
    messages and bytes) globally in `CConnman`. This happens every time
    messages are sent or received. The per-peer stats are lost when a peer
    disconnects.
    
    Also expose this object with a getter.
    c32f277499
  57. rpc: aggregate network message stats
    Aggregate stats to show zero or more of the following dimensions:
    direction, network, connection, message type
    
    The depth of the return object depends the number of dimensions
    specified to be shown. MultiLevelStatsMap makes this possible, and
    converts the object to a UniValue.
    
    Co-authored-by: Anthony Towns <aj@erisian.com.au>
    Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
    ec1dd13113
  58. rpc: create a new getnetmsgstats rpc
    Introduce a new getnetmsgstats rpc that is able to return network
    message statistics arranged in a number of different ways (direction,
    network, connection, message type). If no dimension types are
    specified to be shown, return the totals.
    
    Includes helper code to convert a string to a DimensionType enum.
    
    Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
    23c53cece8
  59. test: add functional tests for getnetmsgstats rpc 1b9fe3b4c6
  60. satsie force-pushed on Jun 2, 2023
  61. satsie commented at 11:28 pm on June 3, 2023: contributor
    Moving to draft as I work through some feedback
  62. satsie marked this as a draft on Jun 3, 2023
  63. DrahtBot added the label Needs rebase on Jul 20, 2023
  64. DrahtBot commented at 10:53 am on July 20, 2023: contributor

    🐙 This pull request conflicts with the target branch and needs rebase.

  65. luke-jr commented at 10:07 pm on July 27, 2023: member
    Is there a use case for this, for the typical user? If not, maybe it should be optional and disabled by default?
  66. vasild commented at 8:11 am on August 4, 2023: contributor
    @luke-jr, for sure there will be people that don’t need this. But it is just an extra RPC, if somebody does not need it, then he/she will not call it. Similar stats are already provided in the getpeerinfo RPC output.
  67. maflcko commented at 4:57 pm on September 20, 2023: member
    Are you still working on this?
  68. satsie commented at 1:06 am on September 22, 2023: contributor
    @willcl-ark is picking this up and will open a follow up PR. Closing
  69. satsie closed this on Sep 22, 2023

  70. vasild commented at 10:14 am on September 22, 2023: contributor
    @willcl-ark, thank you! Here is a branch with some suggestions and ideas you may find useful: https://github.com/vasild/bitcoin/tree/getnetmsgstats
  71. fanquake commented at 4:25 pm on November 22, 2023: member
    Picked up in #28926.

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-06-29 10:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me