39

I read the full api method list and did not seem to find one.

I suppose there is no command specifically for that purpose, so what is the general way of doing this?

I would consider checking the time stamp of the last generated block, but the getblock method is not really explained in much detail.

EDIT:

Some people answer that I should compare the block count with one of an online block chain monitor. That is not really a practical solution. The Bitcoin-Qt client has a way of knowing when syncing is done (the V-sign vs the syncing icon), so why doesn't bitcoind? How does the Bitcoin-Qt get this information?

7

11 Answers 11

20

I use a python script that grabs http://blockchain.info/q/getblockcount and compares it to the output of bitcoind getblockcount.

As others have said, there is no absolute way of telling if your blockchain is up to date.

Anyway, here is my script:

    import httplib2
    from bitcoinrpc.authproxy import AuthServiceProxy
    access = AuthServiceProxy('#########')
    try:
            blockCount = access.getblockcount()
    except Exception as e:
            print "Problems connecting to bitcoin wallet:"
    else:
            try:
                    response, trueBlockCount = httplib2.Http().request("http://blockexplorer.com/q/getblockcount/")
            except Exception as e:
                    print "Unable to get true blockcount from blockexplorer:"+str(e)
            else:
                    if (int(trueBlockCount) - 5) > blockCount :
                            print "blockchain not up to date: true block count is: "+str(trueBlockCount)+", while bitcoind is at: "+str(blockCount)
2
  • pip install httplib2 and git clone github.com/jgarzik/python-bitcoinrpc.git and python setup.py install helped me run this code
    – greg121
    Commented Feb 9, 2015 at 15:21
  • 1
    rather than bitcoind getblockcount don't you mean bitcoin-cli getblockcount?
    – matvore
    Commented Sep 7, 2018 at 5:43
16

There is no way for checking whether syncing is done, simply because it isn't known.

Slightly abstractly, and probably not useful in your case, the client is always syncing: there is no real difference between "having all blocks" and "not having all blocks" - it always has all blocks that it knows about, and doesn't know whether there are blocks which it misses.

What the GUI shows you is a guess. It checks the age of the last known block, and if it is (IIRC) more than 90 minutes ago, it assumes it's out of sync. This is usually a good indicator, but it will rarely yet certainly randomly fail from time to time.

The core code has another heuristic built-in, which uses block heights reported by other nodes (without verifying that information in any way, so it's easily cheated). This information is used to determine whether it should optimize cache behaviour for many fast operations, or reliability. It's not exposed directly either, but the getwork() and getblocktemplate() RPCs will fail in this mode.

1
  • What is the benefit of the heuristic built-in over checking the age of the last known block?
    – Jori
    Commented Nov 17, 2014 at 19:29
12

Bitcoind no longer supports RPC calls. Try:

watch bitcoin-cli getblockchaininfo

When the displayed number of blocks equals the displayed number of headers, you're synced!

4
  • 1
    This doesn't seem to work in all cases. I have a bitcoin-abc (BCH) testnet node which is synced, but headers is still significantly larger than blocks. I think maybe it is getting header counts from BTC nodes. Commented Nov 21, 2017 at 1:33
  • @NateEldredge - how do you know it is synced?
    – Hannah Vernon
    Commented Nov 21, 2017 at 15:11
  • 1
    @MaxVernon: The debug.log has an UpdateTip message showing a block with a recent timestamp, which agrees with the latest block shown by block explorers. Commented Nov 21, 2017 at 23:05
  • If you could include info about how to double check using the age of the last known block, I think this would be the best answer. You know you're not up to date until your latest verified block is the same as your number of headers, but you don't quite know you're up to date even when that happens until you check blocks timestamps vs network time (and your own time)
    – B T
    Commented Dec 15, 2017 at 6:36
11

Considering that you are always somewhat out of sync, here is how you can get by how long in seconds, and then you can divide by 60 or 3600 to get it in minutes or hours.

If you want to do it manually:

# bitcoin-cli getblockcount
2345
# bitcoin-cli getblockhash 2345
000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062
# bitcoin-cli getblock 000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062 | grep "time"
    "time" : 1233313208,
# echo $((`date +%s`-1233313208))
<number of seconds>

Or the same in two steps

bitcoin-cli getblock `bitcoin-cli getblockhash \`bitcoin-cli getblockcount\`` | grep time
    "time" : 1233313208,
echo $((`date +%s`-1233313208))
<number of seconds>

I didn't find a way to do it in one call, so here is a script that does the whole thing, with no error checking as you can see:

#!/bin/bash
cnt=`bitcoin-cli getblockcount`
hash=`bitcoin-cli getblockhash ${cnt}`
timeline=`bitcoin-cli getblock $hash | grep '"time"'`
ltrimtime=${timeline#*time\" : }
newest=${ltrimtime%%,*}
echo $((`date +%s`-$newest))

Then you can replace

echo $((`date +%s`-$newest))

To get the number of minutes like this:

echo $(((`date +%s`-$newest)/60))

Or the number of hours like that:

echo $(((`date +%s`-$newest)/3600))

Or, assuming you have perl (which you probably have) and that you prefer to have the date of the last block:

perl -le "print scalar localtime $newest;"
2
  • The time that is in the block is the time that a miner reported, while it will probably be close to the correct time, it may not be correct. See this question.
    – morsecoder
    Commented Jan 15, 2015 at 23:16
  • I'm trying to use this method to determine the age of the newest block in my wallet's chain, to estimated up-to-date-ness. via RPC calls, I run getblockcount and it returns the block number. Then I run getblockhash $count to get the hash. Everything seems to be going well. But then when I run getblock $hash it throws a parse error, every time (-32700). Any thoughts on why? Despite my variables in this comment, I have confirmed the commands being sent are correct. For example: getblock 000000000000000000114801309313f1fa84f8ce4e6f6e0bcc23eea91aeca343 throws a parse error :(
    – l008com
    Commented Jul 2, 2020 at 9:09
2

Update August 7 2015 ~ start

So after having an IP or two banned because of checking to often... so, I'll provide some options on how to avoid getting banned. First don't use the script under this update; the variable expansion Bash preforms causes multiple calls to https://blockchain.info in to short of a time frame. You can try adding sleep 120 between the assignment and calls but that would be very slow. Second the key things are; Checking local count $(bitcoin-cli getblockcount) and Checking a well known node $(wget -q -O - http://blockchain.info/q/getblockcount) and Checking local sync state $(bitcoin-cli getblocktemplate)

To combine the Blockchain from your node to another in one line

$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))
# To print this with echo and date stamp
echo "    $(date) : $($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))"
# To redirect and exit with 0 : ie place in crontab
echo "$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))" > /var/log/btc_blocks_left_to_sync.log 2>&1

The last one above is likely the best for scripting as the file it saves to can be read for just the number inside or the last time it was modifide.

Update August 7 2015 ~ end

Indeed the correct function call is shown there, @BinaryMage, thank you.

possible duplicate of When downloading the blockchain for the first time, how do I know when it's done? – BinaryMage Apr 4 '13 at 0:50

The person to show the correct function was @LoHoris, however, the updates to Bitcoin node software now uses bitcoin-cli getblocktemplate and not bitcoind for these lookups.

Thanks to both of them it is possible to offer you all a combination of both answers wrapped into a checker script; ready for your customization and updated for the year 2015


    #!/bin/bash
    timed_wait=600
    vars_to_load(){
        ## Set vars to function such that they are set upon every call
        localCheck=$(bitcoin-cli getblockcount)
        crossCheck=$(wget -q -O - http://blockchain.info/q/getblockcount)
        diffBlocks=$(($crossCheck-$localCheck))
        localSize=$(ls -hal ~/.bitcoin/blocks | awk '/total/{print $2}')
    }
    check_sync(){
        while true
        do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
            sleep $timed_wait
        done
    }
    networked_sync(){
        vars_to_load
        ## Function to print difference in node sync
        if [ $diffBlocks -eq 0 ]
        then
            echo "Sync is good with $diffBlocks blocks off"
        else
            echo "Sync has $diffBlocks blocks left to download"
        fi
    }
    check_sync

This script first checks the exit status of bitcoin-cli getblocktemplate because anything other than 0 is usually an error it'll run the other parts only if bitcoin-cli getblocktemplate shows an error. Of course it is possible to check for specific error codes instead and do things for specific error codes... but this works fine as a template for me when setting up BTC nodes in a headless environment. The other checks then compare local block count verses https://blockchain.info and prints out how many blocks your system is off. These only run when local check of sync status error out thus if you're on a slower like @Steven Roose mentioned then this script is ideal.

By default the wait time between checks is 600 seconds (10 minuets) to keep network checks and local checks to a minimum, however, for logging and better resource management it is easy enough to comment out the while, do, and done and sleep $timed_wait lines. And add one line to crontab to accomplish running on a schedule. Last modify the very end of the script to write output to a file.


The function modified;

    check_sync(){
    #   while true
    #   do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
    #       sleep $timed_wait
    #   done
    }

And to run every 10 minuets

    sudo nano /etc/crontab
        */10 *  * * *   root    /pathTo/script.sh 2>&1

Then to enable logging modify the call that starts every thing within the script;

    check_sync | tee -a /tmp/BTCsync_log.txt

Hopefully this is acceptable enough of an answer to mark this question as [Solved] such that future web searchers can have an easier time of this.

2

Not seeing any trivial answers here. Here's what i did.

Use API CALL "getblockchaininfo" Parameter "verificationprogress" will be ~= 1.0, if you are synced.

Warning: this appears to be based on time, your clock will need to be somewhat accurate.

I check that it is >= 0.999 to determine if i'm in sync.

1
  • This seems like a pretty simple, logical way to determine this. Any second or third opinions about using this method? Potential pitfalls?
    – l008com
    Commented Jul 6, 2020 at 12:49
2

A bit hacky, but the debug log shows your "progress" as far as bitcoind is concerned.

tail -n 1 ~/.bitcoin/debug.log

Gives you something like

2016-04-26 19:02:21 UpdateTip: new best=000000000000000002a9b8f81c231c99b86f79fae383fb1fc046974f7fdcf118  height=405098  log2_work=84.399379  tx=119389857  date=2016-03-31 10:06:53 
progress=0.982752  cache=0.5MiB(0tx)

In this case, I'm 98 percent "done".

1

There are some neat solutions here, and maybe this is just overly simple but, if you're legitimately catching up to the blockchain and not basically at the end so only getting that new block once every ~ 10 minutes, look at your cpu usage.

If you're on linux, run "top". bitcoind will be working its butt off calculating every hash of every block through the blockchain. Once it's caught up, it's basically idle.

2
  • Does not work when your internet connection is having issues. Or when your connection is just slow. bitcoind iterates between downloading blocks and verifying them, so in a period of downloading and a slow connection, CPU usage will be low as well. Commented Jan 18, 2015 at 13:01
  • Yes that's true. If you have a slow enough internet connection such that your CPU is only busy hashing every 10 minutes or so, you can't tell the difference between that problem and actually being caught up. However you'll never catch up if you don't outrace the rate at which blocks are created. Even if you're only seeing activity once a minute that's still a clear indiciation that you're catching up. As once you're caught up you'll only have real activity once every 10 minutes.
    – seijirou
    Commented Jan 21, 2015 at 3:33
1

just use the standard bitcoin-cli getblockchaininfo

then check the initialblockdownload field in the response, if this is true, then the node is still synchronizing:

{
  "chain": "main",
  "blocks": 813280,
  "headers": 814250,
  "bestblockhash": "0000000000000000000296fddea58647bc01598bf91f391d081c06ada148efce",
  "difficulty": 61030681983175.59,
  "time": 1697941840,
  "mediantime": 1697939028,
  "verificationprogress": 0.9981760872613284,
  "initialblockdownload": true,
  "chainwork": "000000000000000000000000000000000000000059f423ba44c0a97786f959b1",
  "size_on_disk": 590414048660,
  "pruned": false,
  "warnings": ""
}
1
  • I don't think this is correct. Not sure, I thought once the flag was set to false, it would never go back to zero. So if you start up a node that had been down for some time, it would no longer be an indicator. Commented Nov 12, 2023 at 6:48
0

Throw the script below into your /home/$USER/.bashrc file and restart your shell.

alias bitcoindSynced='

bitcoindSynced() {
blockCount=`bitcoind getblockcount`
blockChain=`wget -O - http://blockchain.info/q/getblockcount`
blockDiff=`expr $blockChain - $blockCount`

if [ $blockDiff = 0 ]
then
    echo "up to date"
else
    echo "$blockDiff blocks behind"
fi
}

bitcoindSynced 2>/dev/null'

Then when you run the command

bitcoindSynced

you will be provided with the number of blocks left to sync,
or if your client is up to date it will let you know.


Also, if you don't want to restart your shell you can just run the command

source /home/$USER/.bashrc

and it will do the same thing.

4
  • 1
    That's a really strange way of doing a bash function definition. Commented May 1, 2013 at 0:39
  • 1
    And I have problems to believe this is the way the Bitcoin-Qt client does it... Commented May 1, 2013 at 0:57
  • How would you do it? It's alised because you need to call the function after with '2>/dev/null' after defining it and you can't do that inside the function or it will repeat forever when the shell starts. I'm no linux guru, if there is a correct way to do it then please teach me :)
    – derrend
    Commented May 1, 2013 at 16:45
  • Also this is not how the Bitcoin-Qt client does it, it's a hack for the bitcoind daemon.
    – derrend
    Commented May 1, 2013 at 16:52
0

More rudimentary but useful to know if the wallet is synchronized or not

By using the commands:

  • "getinfo" (give your current block height)
  • "getpeerinfo" (give the block height with the "startingheight" field for each connection).

Then, you can easly compare values and find out how many percent you are for downloading the blockchain.

1
  • By getinfo I assume you mean getblockchaininfo. If that's true, this doesn't seem to work as the median number from peers right now is 637967 yet getblockchaininfo shows me as having 637974 blocks. So I'm magically ahead of all of my peers. Somethings not right with this method.
    – l008com
    Commented Jul 6, 2020 at 12:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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