def presentblock(endpoint, blockJSON):
    block = dbinterface.blockfromJSON(blockJSON)
    halfhour = timedelta(minutes=30)
    context = dbinterface.getEndpointContext(block.endpoint)
    print("chain length before acceptance is: {}".format(context[2]))

    # We should check if the message came from the endorser. If not, we should
    # check with the endorser in the block. This is not implemented due to time
    # constraints.

    if not dbinterface.isInLedgers(endpoint):
        return "block rejected, endpoint not known"
    if block.endpoint != endpoint:
        return "block rejected, endpoint doesn't match"
    if block.index > context[2] + 1:
        return "block rejected, lacking previous blocks"
    if block.operation != "ADD" and block.operation != "REV" and block.operation != "SMP":
        return "block rejected, operation unknown"
    if (datetime.now() - halfhour > datetime.fromtimestamp(block.timestamp)
            or datetime.now() + halfhour < datetime.fromtimestamp(
                block.timestamp)):
        return "block rejected, timestamp off"
    # if block.previous_hash != dbinterface.getBlock(block.index - 1, endpoint).compute_hash():
    # previous block mismatch
    # return "block rejected, hash mismatch"
    dbinterface.getBlock(block.index - 1, endpoint).compute_hash()
    #TODO: reject block if a copy is already known
    #TODO: reject block if whitebox is already known
    #TODO: reject block for other reasons

    #TODO: Drop blocks that may now be invalid, or reject block for stored block with precedent

    #TODO: store block if accepted
    if block.index == context[2] + 1:
        dbinterface.addBlock(block, endpoint)
        return "block accepted"
    else:
        #TODO: compare block with stored block for timestamp, find correct chain,
        # reject other chain.
        print("index wrong: got {}, should be {}".format(
            block.index, context[2] + 1))
        return "block accepted, but not stored(implementation)"
def validatestoredledger(endpoint, endorsercount):
    context = dbinterface.getEndpointContext(endpoint)
    if context[1] != endpoint:
        return False
    lastblock = dbinterface.getBlock(context[2], endpoint)
    lasthash = lastblock.compute_hash()

    #TODO: local hash validation

    # Remote validation
    references = downloadremotereferences(endpoint, endorsercount)
    successes = 0
    for reference in references:
        request_url = "http://{}/getlastblockhash/{}".format(
            reference, endpoint)
        r = requests.get(request_url)
        print("received hash: {} my hash: {}".format(r.text, lasthash))
        if r.text == lasthash:
            successes += 1

    if successes > endorsercount / 2:
        return True
    return False
def revoketrust(endpoint):

    context = dbinterface.getContext()
    endpointContext = dbinterface.getEndpointContext(endpoint)

    if dbinterface.isInLedgers(endpoint):
        prev_block_hash = dbinterface.getBlock(endpointContext[2],
                                               endpoint).compute_hash()
        my_registration_block = Block(endpointContext[2] + 1, "REV",
                                      datetime.timestamp(datetime.now()), 1,
                                      prev_block_hash, context[1], endpoint)

        if pushblocktopeers(endpoint, my_registration_block, 3):
            dbinterface.addBlock(my_registration_block, endpoint)
            dbinterface.deleteLedgerEntry(endpoint)
            os.remove("{}.db".format(endpoint))
            return "Trust succesfully revoked"
        else:
            return "block push to peers failed. Revoke failed."

    else:
        return "endpoint {} not known, no trust exists to be revoked".format(
            endpoint)
def trust(endpoint):
    """
    Establish this whitebox as a endorser for endpoint.
    """

    context = dbinterface.getContext()

    if dbinterface.isInLedgers(endpoint):
        #Ledger is locally available, therefore the whitebox already endorses endpoint
        return "Whitebox is already an endorser"
    else:
        request_url = "{}/getnumendorsers/{}".format(discovery_server,
                                                     endpoint)
        r = requests.get(request_url)
        if r.status_code != 200:
            return "Discovery server error, endorse failed"

        if r.text == "0":
            #entirely new ledger
            msg = setupNewLedger(endpoint)
            request_url = "{}/register@{}&{}".format(discovery_server,
                                                     context[1], endpoint)
            r = requests.get(request_url)
            if r.status_code == 200:
                if r.text == "now endorsing endpoint " + str(endpoint):
                    print(
                        "Registration succeeded, but other registration already exists. Should now discover other endorser, but this is not implemented"
                    )
            else:
                print(
                    "Registration failed. Should be retried automatically, but this is not implemented"
                )
            return msg
        else:
            #ledger exists elsewhere
            other_endorsers_count = int(r.text)
            references_used = other_endorsers_count
            if references_used > verify_with_count:
                references_used = verify_with_count

            reference = downloadremotereferences(endpoint, 1)[0]

            downloadremoteledger(endpoint, reference)

            if validatestoredledger(endpoint, references_used):
                # make ledgers entry
                with sl.connect('trustledgers.db') as con:
                    con.execute('INSERT INTO LEDGERS (id, name) values(?, ?)',
                                (context[2] + 1, endpoint))
                dbinterface.setNumledgers(context[2] + 1)

                endpointContext = dbinterface.getEndpointContext(endpoint)

                #make registration block
                prev_block_hash = dbinterface.getBlock(
                    endpointContext[2], endpoint).compute_hash()
                my_registration_block = Block(
                    endpointContext[2] + 1, "ADD",
                    datetime.timestamp(datetime.now()), 1, prev_block_hash,
                    context[1], endpoint)

                # add block to own ledger
                dbinterface.addBlock(my_registration_block, endpoint)

                if not pushblocktopeers(endpoint, my_registration_block, 2):
                    return "Trust-link failed, coulnd't establish with peers. Should be retried later automatically, but this is not implemented"

                # register with discovery_server
                request_url = "{}/register@{}&{}".format(
                    discovery_server, context[1], endpoint)
                r = requests.get(request_url)
                if r.status_code == 200:
                    return "Trust-link succesfully established"
                else:
                    return "Trust-link establishment succeeded, but discovery server registration failed. Should retry automatically, but this is not implemented"
            else:
                return "Trust-link failed, ledger verification failed"

    return 'trust failed'
def getlastblockhash(endpoint):
    context = dbinterface.getEndpointContext(endpoint)
    if context[1] != endpoint:
        return False
    lastblock = dbinterface.getBlock(context[2], endpoint)
    return lastblock.compute_hash()