Synchronize our local block headers up to the last block ID given.
        @last_block_id is *inclusive*
        @bitcoind_server is host:port or just host

def sync_header_chain(cls, path, bitcoind_server, last_block_id ):
        """
        Synchronize our local block headers up to the last block ID given.
        @last_block_id is *inclusive*
        @bitcoind_server is host:port or just host
        """
        current_block_id = SPVClient.height( path )
        if current_block_id is None:
            assert USE_TESTNET
            current_block_id = -1

        assert (current_block_id >= 0 and USE_MAINNET) or USE_TESTNET

        if current_block_id < last_block_id:
          
            if USE_MAINNET:
                log.debug("Synchronize %s to %s" % (current_block_id, last_block_id))
            else:
                log.debug("Synchronize testnet %s to %s" % (current_block_id + 1, last_block_id ))

            # need to sync
            if current_block_id >= 0:
                prev_block_header = SPVClient.read_header( path, current_block_id )
                prev_block_hash = prev_block_header['hash']

            else:
                # can only happen when in testnet
                prev_block_hash = GENESIS_BLOCK_HASH_TESTNET

            # connect 
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            # timeout (10 min)
            sock.settimeout(600)

            bitcoind_port = 8333
            if ":" in bitcoind_server:
                p = bitcoind_server.split(":")
                bitcoind_server = p[0]
                bitcoind_port = int(p[1])

            log.debug("connect to %s:%s" % (bitcoind_server, bitcoind_port))
            sock.connect( (bitcoind_server, bitcoind_port) )

            client = BlockHeaderClient( sock, path, prev_block_hash, last_block_id )

            # get headers
            client.run()

            # verify headers
            if SPVClient.height(path) < last_block_id:
                raise Exception("Did not receive all headers up to %s (only got %s)" % (last_block_id, SPVClient.height(path)))

            # defensive: make sure it's *exactly* that many blocks 

            rc = SPVClient.verify_header_chain( path )
            if not rc:
                raise Exception("Failed to verify headers (stored in '%s')" % path)

        log.debug("synced headers from %s to %s in %s" % (current_block_id, last_block_id, path))
        return True