'Handle receiving a single block header'

def on_get_header(self, interface, response):

    header = response.get('result')
    if (not header):
        interface.print_error(response)
        self.connection_down(interface.server)
        return
    height = header.get('block_height')
    if (interface.request != height):
        interface.print_error('unsolicited    header', interface.request, height)
        self.connection_down(interface.server)
        return
    chain = blockchain.check_header(header)
    if (interface.mode == 'backward'):
        if chain:
            interface.print_error('binary    search')
            interface.mode = 'binary'
            interface.blockchain = chain
            interface.good = height
            next_height = ((interface.bad + interface.good) // 2)
        elif (height == 0):
            self.connection_down(interface.server)
            next_height = None
        else:
            interface.bad = height
            interface.bad_header = header
            delta = (interface.tip - height)
            next_height = max(0, (interface.tip - (2 * delta)))
    elif (interface.mode == 'binary'):
        if chain:
            interface.good = height
            interface.blockchain = chain
        else:
            interface.bad = height
            interface.bad_header = header
        if (interface.bad != (interface.good + 1)):
            next_height = ((interface.bad + interface.good) // 2)
        elif (not interface.blockchain.can_connect(interface.bad_header, check_height=False)):
            self.connection_down(interface.server)
            next_height = None
        else:
            branch = self.blockchains.get(interface.bad)
            if (branch is not None):
                if branch.check_header(interface.bad_header):
                    interface.print_error('joining    chain', interface.bad)
                    next_height = None
                elif branch.parent().check_header(header):
                    interface.print_error('reorg', interface.bad, interface.tip)
                    interface.blockchain = branch.parent()
                    next_height = None
                else:
                    interface.print_error('checkpoint    conflicts    with    existing    fork', branch.path())
                    branch.write('', 0)
                    branch.save_header(interface.bad_header)
                    interface.mode = 'catch_up'
                    interface.blockchain = branch
                    next_height = (interface.bad + 1)
                    interface.blockchain.catch_up = interface.server
            else:
                bh = interface.blockchain.height()
                next_height = None
                if (bh > interface.good):
                    if (not interface.blockchain.check_header(interface.bad_header)):
                        b = interface.blockchain.fork(interface.bad_header)
                        self.blockchains[interface.bad] = b
                        interface.blockchain = b
                        interface.print_error('new    chain', b.checkpoint)
                        interface.mode = 'catch_up'
                        next_height = (interface.bad + 1)
                        interface.blockchain.catch_up = interface.server
                else:
                    assert (bh == interface.good)
                    if ((interface.blockchain.catch_up is None) and (bh < interface.tip)):
                        interface.print_error(('catching    up    from    %d' % (bh + 1)))
                        interface.mode = 'catch_up'
                        next_height = (bh + 1)
                        interface.blockchain.catch_up = interface.server
            self.notify('updated')
    elif (interface.mode == 'catch_up'):
        can_connect = interface.blockchain.can_connect(header)
        if can_connect:
            interface.blockchain.save_header(header)
            next_height = ((height + 1) if (height < interface.tip) else None)
        else:
            interface.print_error('cannot    connect', height)
            interface.mode = 'backward'
            interface.bad = height
            interface.bad_header = header
            next_height = (height - 1)
        if (next_height is None):
            interface.print_error('catch    up    done', interface.blockchain.height())
            interface.blockchain.catch_up = None
            self.switch_lagging_interface()
            self.notify('updated')
    elif (interface.mode == 'default'):
        if (not ok):
            interface.print_error(('default:    cannot    connect    %d' % height))
            interface.mode = 'backward'
            interface.bad = height
            interface.bad_header = header
            next_height = (height - 1)
        else:
            interface.print_error('we    are    ok', height, interface.request)
            next_height = None
    else:
        raise BaseException(interface.mode)
    if next_height:
        if ((interface.mode == 'catch_up') and (interface.tip > (next_height + 50))):
            self.request_chunk(interface, (next_height // 2016))
        else:
            self.request_header(interface, next_height)
    else:
        interface.mode = 'default'
        interface.request = None
        self.notify('updated')
    self.notify('interfaces')
