Context:

I'm working on an application in which we'd like to know if the current node is sufficiently synced to be able to handle RPC requests. The method we would like to use is to see if our node has at least 2-4 peers and if a majority of the peers are reporting the same best height / best block hash.


Previous research:

  • I know the version network call gets the height of the peer at that time, but it isn't updated. In addition, any further version requests result in an increase of the ban score of a node, so this cannot be used frequently.
  • Bitcoinj keeps track of the height of the best known peer by using the height given in the version message and then incrementing whenever the peer processes an inv message showing they have a new best-block height. This seems fast, but tricky/error prone.
  • This question is similar, but it asks about how to do this with RPC calls, and it doesn't seem to want to use the same method for determining whether the node is synced as the one I've proposed.
  • This question helped provide a temporary solution (calling get work and seeing if it fails), but this method is not accurate enough.

Is there a way to just ask a peer what the height of its best block is without getting banned?

Could I just make multiple getheaders requests and see if the peer returns any headers later than the header I have, or would the peer ban me for requesting the same headers again and again?

up vote 3 down vote accepted

Bitcoin Core 0.10.0 may provide the solution you need thanks to its headers-first synchronization. The getblockchaininfo RPC in 0.10.0 provides both a blocks field (the number of verified blocks) and a headers field (the number of partially-validated headers).

Any time the numbers differ, you don't have all the blocks. During Initial Block Download (IBD), they'll be hundreds of thousands of blocks apart. (According to a Wireshark sniff I did during IBD a few weeks ago, it took my node less than two minutes to download a complete headers chain; syncing the blocks then took another three hours.)

Bitcoin Core 0.10.0 has two other new fields you might find useful, both in the getpeerinfo RPC. The fields are synced_headers and synced_blocks. The headers field is based on the last P2P headers message the remote node sent you. The blocks field is based on the last P2P block inv message the peer sent you. In both cases, they let you know the last header or block you have in common with the remote node (as best as can be determined).

I don't know how useful these getpeerinfo fields will be, as your node can't tell you the height of a block until it has the corresponding block header---at which point the getblockchaininfo RPC will already tell you that you're out of sync. However, they are kinda fun to look at.


Could I just make multiple getheaders requests and see if the peer returns any headers later than the header I have, or would the peer ban me for requesting the same headers again and again?

As far as I know, there's no ban score there (as long as your packets are valid). However, the remote peer should send you an inv message as soon as it validates an incoming block---so there's no need to poll it as long as your app handles inv messages with a MSG_BLOCK type.

  • Is it guaranteed that nodes will send you an inv right after they have a new best block every time? Even if you are the one who sent them the new block data? – StephenM347 Jan 16 '15 at 0:45
  • If you send them an inv, they shouldn't send you an inv for the same data. Bitcoin Core also won't send invs while they're in IBD. For all other cases, Bitcoin Core full nodes will send you an inv for each new block they validate. Based on my reading of the 0.10.0 code a few weeks ago, there is no built-in delay (like for tx invs) or network partitioning (like for addrs) when it comes to block invs. Of course, nothing is guaranteed on a P2P network. – David A. Harding Jan 16 '15 at 1:22
  • Doesn't the bitcoin method depend on using headers first synchronization? The fields added to getpeerinfo may be just what I need. False negatives (reporting that the node is not sufficiently caught up to handle requests when they actually are) are fine, it's false positives that would be the real kicker. I think the methods in the new getpeerinfo should meet those requirements. So, thanks! – StephenM347 Jan 16 '15 at 2:29
  • Yes, headers first is required, which is why only 0.10.0 has that field. Note that it works the same whether or not the remote node uses headers first (0.10.0 won't connect to nodes that don't support the P2P headers/getheaders messages, which were introduced in December 2010). I'd think the headers field from getblockchaininfo would be more useful because it has the height of the highest of your peer connections (so you don't need to iterate over each connection). – David A. Harding Jan 16 '15 at 2:48
  • Yes, it probably would be a faster response time and more useful, but we are working with coins other than just Bitcoin (Lite, Doge, etc), and we need the sync check for all of them. Implementing headers first synchronization in all these coins probably isn't doable in the time frame. – StephenM347 Jan 16 '15 at 3:46

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.