I added ping time measurement to bitcoind, and it works, using the "ping" and "pong" commands (ping sends a unique nonce, pong echoes that nonce).
I added the ping time as an additional output to getpeerinfo. The ping time is in seconds, as a decimal number, so it often appears as a very small decimal number with many places, looking rather appropriate for Bitcoin
Now, I can see, in the table of connected peers, the ping time for each peer. The ping command is handled in the normal command handling function, it isn't given additional priority or anything like that, so the ping time also includes all command processing backlog time, revealing which nodes are heavily congested with commands to be processed (such as nodes trying to catch up on blockchain synchronization).
I also added a new RPC command, "ping", to request that a ping command be sent out to all peers. This is in additional to the usual case of sending out the ping command as a keepalive.
It's not ready for pull request yet, but to take a look at it, it's here:
https://github.com/Krellan/bitcoin/commit/fbc91c10d818432070ef8bac56b07707f43ef0b1Interesting observations:
1) The reference bitcoind sends ping commands with 0 (zero) as a nonce, however, during my testing I encountered other peers that sent me valid nonces (nonzero, looks random enough to me). So, there must be other patches floating around that also add valid nonces to the ping command?
2) I noticed a lot of nonce mismatches. Upon further inspection, there are a lot of peers that send a pong reply with 0 (zero) as the nonce, regardless of what I had sent to it in the original ping command. I wonder what causes this? The reference bitcoind doesn't do this, it is correct, and it looks like a bug in some other client.
3) In my implementation I only keep track of one outstanding nonce/timestamp at a time. There's nothing stopping the user from sending another ping while still waiting for the first to complete, though. I wonder if it is worth it to complicate the implementation by using a vector so I can remember more than one nonce/timestamp at a time per node, or only consider the most recent ping attempt to be the only valid ping?
4) I'm using a unique random nonce for each peer, which is rather wasteful of valuable random number entropy. Perhaps use the same nonce for all peers in a single ping command, or would that open up other problems?
5) Adding the new RPC command "ping" opens up an opportunity for a user with RPC access to attempt to DoS the rest of the Bitcoin network, by sending out ping commands as fast as possible. I need to ratelimit this. Any suggestions on what a reasonable ratelimit would be?
6) Similarly to the above, if a peer is sending me ping commands too quickly, I should also ratelimit my pong replies. Any suggestions for that? There are other things as well, such as sending me unsolicited pong commands (without a corresponding ping). If peer is doing these, should I punish them with Misbehaving() or just silently ignore them?
Thanks!
This is a rather cool feature, I'm happy about it, and it was inspired by the "pings" webpage of p2pool.
Josh