Half-executed update call (Replica bug?)

I do a HTTPS request to my software (further “the proxy”):

public func checkedHttpRequest(checker: HttpRequestsChecker, request: Types.HttpRequestArgs, params: {timeout: Nat}): async* Types.HttpResponsePayload {
    announceHttpRequest(checker, request, params);
    await Types.ic.http_request(request);
};

Then the proxy checks by calling back to IC that the request has been recently “announced” (that announceHttpRequest has been called recently) by calling back as update:

public shared func checkRequest(hash: Blob): async () {
    if (not Http.checkHttpRequest(requestsChecker, hash)) {
        Debug.trap("hacked HTTP request");
    }
};

I, apparently, have the following problem: the checkRequest call from the proxy happens before IC saves in the state that the call has been announced. So, proxy mistakenly assumes that it has been hacked.

But I don’t understand how that can happen: After the request was announced (call of announceHttpRequest) it is placed await, that is Types.ic.http_request should behave like a separate update call. That is, http_request should happen only after the announceHttpRequest is fully finished (there is a consensus that the HTTP request has been announced). But the proxy, as I explained above, is not informed that it has been announced. Is it a bug?

Note that I tested it as dfx start (without additional arguments) inside a docker container on localhost.

If it is a bug (and I think so, atomicity of operations is broken), should I create a minimal testing example (possibly, as a Docker container running IC and a server)?

This an async * type and you are not await* in your second function so it is a future and never null? But maybe there are two checkHttpRequest?

I don’t understand your question. There is just one checkHttpRequest and there is also checkRequest (see above).

Here is checkHttpRequest:

    public func checkHttpRequest(checker: HttpRequestsChecker, hash: Blob): Bool {
        BTree.has(checker.hashes, Blob.compare, hash);
    };

Probably, this isn’t a bug because “There is no particular order guarantee for ingress messages submitted via the HTTPS interface.”.

But this ordering would be useful. Probably we should add Types.ic.http_request_sync with the order guarantee?

Oh, I am not sure that the problem (with order of operations) that I raised really exists. Maybe, it was my mis-testing.

Apparently, there is no bug. I just tested it wrong. Sorry for a fake alarm.

1 Like