<h2>Existing Methods</h2>
<p>The Bitcoin client does have a way of detecting if it is not sufficiently synchronized. However, to my knowledge, it's not really exposed to RPC in a nice way.</p>
<p>It's called <code>IsInitialBlockDownload()</code>, and it will consider itself not synchronized if any of the following are true:</p>
<ul>
<li>The client is importing from bootstrap.dat or reindexing the blocks it has.</li>
<li>The client has not reached all of its block <a href="https://en.bitcoin.it/wiki/Checkpoint_Lockin" rel="nofollow noreferrer">checkpoints</a>.</li>
<li>The client has received and verified a block in the last 10 seconds AND that block has a timestamp of more than 24 hours ago.</li>
</ul>
<p>You can call <code>getblocktemplate</code>, and if <code>IsInitialBlockDownload()</code> is true, it will come back with an error of <code>RPC_CLIENT_IN_INITIAL_DOWNLOAD</code> (or -10).</p>
<h3>Drawbacks</h3>
<ul>
<li>If your Bitcoin node is down for less than 24 hours, this won't detect anything wrong when it comes back up.</li>
<li>It's a bit ugly.</li>
<li>When your client gets within 24 hours of the current block, it'll think it's up to date, when it probably needs to get ~144 blocks.</li>
<li>If your client stops downloading blocks while it's still synchronizing, this won't detect anything wrong.</li>
</ul>
<h2>New RPC call</h2>
<p>Let's suppose that we're designing a new RPC call from scratch. As other posters have noted, it's not possible to determine this perfectly in the presence of malicious actors. What factors could we measure to make an educated guess?</p>
<ul>
<li>Node uptime. Has the node been up for at least five minutes?</li>
<li>Node downtime. Has the node been down recently? If so, take the amount of time that it was down, and divide it a thousand. If your node has not been up at least that long, then it is not synchronized.</li>
<li>Block timestamp. The network is fairly liberal about enforcing this rule, but my unscientific guess is that it's usually within half an hour or so. You could use this information in a similar way to how <code>IsInitialBlockDownload()</code> does.</li>
<li>Block height of central node. This is the &quot;Look at blockheight of blockexplorer,&quot; solution mentioned in the other question.</li>
<li>Your method would probably work. The only issue I can think of is that if you connected to another node that was still syncronizing, you'd fail to fail.</li>
</ul>

CC BY-SA 3.0
2014-11-17T19:57:27.327Z
What if the client has received a block recently but it is not done processing it, what will `getblocktemplate` do in this case?
morsecoder
CC BY-SA 3.0
2014-11-17T20:00:03.123Z
@StephenM347 It looks at when it finished validating the tip of the best blockchain. (So, it doesn't take blocks that haven't been validated into account.)
Nick ODell
CC BY-SA 3.0
2014-11-17T20:02:45.783Z
Okay, thanks. I wish this were exposed in the RPC interface in a less hacky way.
morsecoder
CC BY-SA 3.0
2014-11-17T20:06:15.440Z
So won't this method fail if the client is synced past all of the checkpoints, but has been offline for like 8 hours?
morsecoder
CC BY-SA 3.0
2014-11-17T21:20:16.600Z
@StephenM347 Well, it'll fail to fail. :) In all seriousness, you're correct.
Nick ODell
CC BY-SA 3.0
2014-11-17T21:27:55.767Z
So, unfortunately this doesn't really solve the problem then... :/
morsecoder
CC BY-SA 3.0
2014-11-17T21:33:55.063Z
But it does answer my question, so if you update it to include the stuff you told me in this commenting, I'll mark is as the right answer. And adding a new RPC call could fix this, you think, right?
morsecoder
CC BY-SA 3.0
2014-11-17T19:49:57.840Z
2014-11-18T05:26:07.967Z
2020-06-16T11:10:03.350Z
Nick ODell
<p>Well bitcoind is <a href="https://github.com/bitcoin/bitcoin" rel="nofollow">opensource</a> so it is entirely possible for you to try to integrate something like that yourself. However, rather than make changes to the base code, you might be able to get similar functionality using the rpc calls that are already implemented. Essentially, the bitcoin client already somewhat does what you're explaining. When you connect to a peer, part of the handshake process is sharing each other's current block; if one is higher than the other's and is valid, the other starts to download from the more current peer. If you look at the debug.log file you can see this happening, along with a running "progress" field that gets logged showing you the percentage you have downloaded.</p>

<p>However for your idea, where you aggregate information, you can try using the "getpeerinfo" rpc call. You could take the information from there and analyse it in anyway you wish without having to to make a native rpc call.</p>

CC BY-SA 3.0
2014-11-17T19:47:23.570Z
2014-11-17T19:47:23.570Z
CJ-Coinsetter
<p>May or may not be of use to you, but just to check sometimes I have a little script/webpage that gets the current block height from each of my bitcoind nodes - if any of them are lower than the majority then they are out of sync. Obviously you'd need nodes on different networks and machines else an error could mean all nodes are out of sync. Works for me though, it's simple and uses an existing RPC call.</p>

CC BY-SA 3.0
2014-11-18T03:44:53.463Z
2014-11-18T03:44:53.463Z
George
<p>No, there is no way to tell, because there is no definition of "being synchronized". Are you still synchronized at the very moment some miner finds a new block? How would you know?</p>

<p>What you describe has no benefit over the already implemented methods of detecting whether the node is far behind (also it is already implemented as Pieter Wuille explains in the answer you linked, though it is not available in the API).</p>

<p>What is it exactly what to try to achieve with this information? Why do you need to know if a server is sufficiently synchronized? You will encounter the real blocks much sooner than any reasonable attacker can generate them.</p>

CC BY-SA 3.0
2014-11-17T19:54:26.290Z
Example usage: You have an payment processing application, and you want it to disable itself if it's blockchain download is not up to date, rather than some features mysteriously not working.
Nick ODell
CC BY-SA 3.0
2014-11-17T19:55:30.833Z
Just like Nick said.
morsecoder
CC BY-SA 3.0
2014-11-17T19:59:34.510Z
@StephenM347 How many payment processing application do not run continuously? Even then, you can still just check the time stamp in the last block and compare it to the system time. I don't see the advantage.
Jori
CC BY-SA 3.0
2014-11-17T20:22:33.213Z
Those timestamps in blocks are pretty unreliable, so I don't think that's a possibility. We have a more complicated use case in mind, but I don't really want to go too far into it. What we really want is a way to know if a server is too far behind to be reliable.
morsecoder
CC BY-SA 3.0
2014-11-17T20:26:10.473Z
And even if it runs continuously, you need to know when it's ready after the initial download.
morsecoder
CC BY-SA 3.0
2014-11-17T20:46:00.647Z
@StephenM347 Why are they not reliable? They are at least equally reliable as querying random unverifiable nodes for their block height.
Jori
CC BY-SA 3.0
2014-11-17T21:31:53.817Z
They're not reliable because miners change them frequently to get more work, and the network allows for a certain amount of flexibility when interpreting these block times. I don't think they would be as reliable as querying the nodes who you are connected to, since bitcoin only really works if most nodes are honest nodes.
morsecoder
CC BY-SA 3.0
2014-11-17T19:35:02.747Z
2014-11-17T19:35:02.747Z
Jori
<p>After reading <a href="https://bitcoin.stackexchange.com/a/10443/18196">this answer</a>, where Peter Wuille talks about how a node can't really tell if it is synced or not, it got me wondering if there is a way we can tell that a node is as synced as it possibly can be given the peers it is connected to. </p>

<p>Could we add an RPC call like <code>getsyncstatus</code> that would have the node ask its peers for their highest known blocks and if a majority (or some percentage) of their peers all agree on the best known block height, then it could use that info to be able to say (with not perfect reliability) how synced the node is?</p>

<p>So, for example, if a node has 8 peers, and 7 of them are returning <code>330448</code> as the best block height, and the client has information about block <code>330448</code>, then it could give a status code and message signalling that it is up to date. If the peers give different answers (which could happen if you connect to a malicious node that is falsely reporting it's best known height OR if other peers are not fully synced), then it could give a status code and a message indicating that the search was inconclusive and they should try again later. And lastly, if 87.5% of nodes are saying <code>330448</code> and the node is only synced up to block <code>1000</code>, then it can give a status code and message indicating that the node is likely not sufficiently synchronized. </p>

<p>I think this would mainly be useful as a way to determine whether servers are sufficiently synchronized with the network for use on some application. The responses to <a href="https://bitcoin.stackexchange.com/questions/4394/when-downloading-the-blockchain-for-the-first-time-using-bitcoind-how-do-i-know">this question</a> describes a way to see if nodes are up to date, but they all seem kind of hacky, and I'm not sure they would be reliable enough.</p>

<json-rpc><synchronization>
Would it be possible to add an RPC call to be able to determine if a node is fully synced?
morsecoder
# Would it be possible to add an RPC call to be able to determine if a node is fully synced?

(Asked by: username_0 on 2014-11-17)

After reading [this answer](https://bitcoin.stackexchange.com/a/10443/18196), where Peter Wuille talks about how a node can't really tell if it is synced or not, it got me wondering if there is a way we can tell that a node is as synced as it possibly can be given the peers it is connected to.

Could we add an RPC call like `getsyncstatus` that would have the node ask its peers for their highest known blocks and if a majority (or some percentage) of their peers all agree on the best known block height, then it could use that info to be able to say (with not perfect reliability) how synced the node is?

So, for example, if a node has 8 peers, and 7 of them are returning `330448` as the best block height, and the client has information about block `330448`, then it could give a status code and message signalling that it is up to date. If the peers give different answers (which could happen if you connect to a malicious node that is falsely reporting it's best known height OR if other peers are not fully synced), then it could give a status code and a message indicating that the search was inconclusive and they should try again later. And lastly, if 87.5% of nodes are saying `330448` and the node is only synced up to block `1000`, then it can give a status code and message indicating that the node is likely not sufficiently synchronized.

I think this would mainly be useful as a way to determine whether servers are sufficiently synchronized with the network for use on some application. The responses to [this question](https://bitcoin.stackexchange.com/questions/4394/when-downloading-the-blockchain-for-the-first-time-using-bitcoind-how-do-i-know) describes a way to see if nodes are up to date, but they all seem kind of hacky, and I'm not sure they would be reliable enough.

**Tags:** json-rpc, synchronization


---

## 4 answers

### Answer by username_1 on 2014-11-17. Score: 2 | Accepted answer

## Existing Methods

The Bitcoin client does have a way of detecting if it is not sufficiently synchronized. However, to my knowledge, it's not really exposed to RPC in a nice way.

It's called `IsInitialBlockDownload()`, and it will consider itself not synchronized if any of the following are true:

* The client is importing from bootstrap.dat or reindexing the blocks it has.
* The client has not reached all of its block [checkpoints](https://en.bitcoin.it/wiki/Checkpoint_Lockin).
* The client has received and verified a block in the last 10 seconds AND that block has a timestamp of more than 24 hours ago.

You can call `getblocktemplate`, and if `IsInitialBlockDownload()` is true, it will come back with an error of `RPC_CLIENT_IN_INITIAL_DOWNLOAD` (or -10).

### Drawbacks

* If your Bitcoin node is down for less than 24 hours, this won't detect anything wrong when it comes back up.
* It's a bit ugly.
* When your client gets within 24 hours of the current block, it'll think it's up to date, when it probably needs to get ~144 blocks.
* If your client stops downloading blocks while it's still synchronizing, this won't detect anything wrong.

## New RPC call

Let's suppose that we're designing a new RPC call from scratch. As other posters have noted, it's not possible to determine this perfectly in the presence of malicious actors. What factors could we measure to make an educated guess?

* Node uptime. Has the node been up for at least five minutes?
* Node downtime. Has the node been down recently? If so, take the amount of time that it was down, and divide it a thousand. If your node has not been up at least that long, then it is not synchronized.
* Block timestamp. The network is fairly liberal about enforcing this rule, but my unscientific guess is that it's usually within half an hour or so. You could use this information in a similar way to how `IsInitialBlockDownload()` does.
* Block height of central node. This is the "Look at blockheight of blockexplorer," solution mentioned in the other question.
* Your method would probably work. The only issue I can think of is that if you connected to another node that was still syncronizing, you'd fail to fail.

> **Comments:**
> **username_0**: What if the client has received a block recently but it is not done processing it, what will `getblocktemplate` do in this case?  
> **username_1**: @StephenM347 It looks at when it finished validating the tip of the best blockchain. (So, it doesn't take blocks that haven't been validated into account.)  
> **username_0**: Okay, thanks. I wish this were exposed in the RPC interface in a less hacky way.  
> **username_0**: So won't this method fail if the client is synced past all of the checkpoints, but has been offline for like 8 hours?  
> **username_1**: @StephenM347 Well, it'll fail to fail. :) In all seriousness, you're correct.  
> **username_0**: So, unfortunately this doesn't really solve the problem then... :/  
> **username_0**: But it does answer my question, so if you update it to include the stuff you told me in this commenting, I'll mark is as the right answer. And adding a new RPC call could fix this, you think, right?  

---

### Answer by username_2 on 2014-11-17. Score: 1

Well bitcoind is [opensource](https://github.com/bitcoin/bitcoin) so it is entirely possible for you to try to integrate something like that yourself. However, rather than make changes to the base code, you might be able to get similar functionality using the rpc calls that are already implemented. Essentially, the bitcoin client already somewhat does what you're explaining. When you connect to a peer, part of the handshake process is sharing each other's current block; if one is higher than the other's and is valid, the other starts to download from the more current peer. If you look at the debug.log file you can see this happening, along with a running "progress" field that gets logged showing you the percentage you have downloaded.

However for your idea, where you aggregate information, you can try using the "getpeerinfo" rpc call. You could take the information from there and analyse it in anyway you wish without having to to make a native rpc call.


---

### Answer by username_3 on 2014-11-18. Score: 1

May or may not be of use to you, but just to check sometimes I have a little script/webpage that gets the current block height from each of my bitcoind nodes - if any of them are lower than the majority then they are out of sync. Obviously you'd need nodes on different networks and machines else an error could mean all nodes are out of sync. Works for me though, it's simple and uses an existing RPC call.


---

### Answer by username_4 on 2014-11-17. Score: 1

No, there is no way to tell, because there is no definition of "being synchronized". Are you still synchronized at the very moment some miner finds a new block? How would you know?

What you describe has no benefit over the already implemented methods of detecting whether the node is far behind (also it is already implemented as Pieter Wuille explains in the answer you linked, though it is not available in the API).

What is it exactly what to try to achieve with this information? Why do you need to know if a server is sufficiently synchronized? You will encounter the real blocks much sooner than any reasonable attacker can generate them.

> **Comments:**
> **username_1**: Example usage: You have an payment processing application, and you want it to disable itself if it's blockchain download is not up to date, rather than some features mysteriously not working.  
> **username_0**: Just like username_1 said.  
> **username_4**: @StephenM347 How many payment processing application do not run continuously? Even then, you can still just check the time stamp in the last block and compare it to the system time. I don't see the advantage.  
> **username_0**: Those timestamps in blocks are pretty unreliable, so I don't think that's a possibility. We have a more complicated use case in mind, but I don't really want to go too far into it. What we really want is a way to know if a server is too far behind to be reliable.  
> **username_0**: And even if it runs continuously, you need to know when it's ready after the initial download.  
> **username_4**: @StephenM347 Why are they not reliable? They are at least equally reliable as querying random unverifiable nodes for their block height.  
> **username_0**: They're not reliable because miners change them frequently to get more work, and the network allows for a certain amount of flexibility when interpreting these block times. I don't think they would be as reliable as querying the nodes who you are connected to, since bitcoin only really works if most nodes are honest nodes.  

---

