Major cross-canister query call delay

Yes, it has to return the same value on all replicas.

1 Like

Does this means ic0.time also goes through concensus protocol to be agreed upon? If not what mechanism is used to ensure it’s the same across the whole subnet?

Yes, that too. Time is part of the block.

2 Likes

That’s unexpected.
How do nodes handle network latency in that case?

Let’s imagine some abstract time-syncing protocol.
X wants to sync its clock with Y.
They initiate the procedure.
Y sends its current time.now() to X.
The message flies through the net.
X receives the message and sees the timestamp.
What should X do? There is no way for X to tell precisely how much time did RTT take this time. Especially in nanoseconds (since ic’s time API operates with nanoseconds).

Could you help me to understand it? I’ve never heard of such algorithms.

According to the spec:

  • within an invocation of one entry point, the time is constant.

Base on this line, my educated guess is:

  1. Timestamp is included in the input block, it marks the starting point of current block. It is the system time of the block maker node, and should closely track physical time.
  2. When a replica receives the block and start to process the messages inside, first thing it does is to blindly sync its internal clock to this timestamp. This “clock” is conceptual, doesn’t need to be accurate relative to physical time.
  3. The spec says, time is constant during processing each message. Thus this conceptual “time” is not continuous in IC, it elapses on a per-message basis.
  4. The elapse interval between two consecutive messages is calculated based on cycles consumed during processing first message.
1 Like

Looks like I figured out why we don’t understand each other.
At the beginning of our conversation yesterday you did propose an alternative solution for RNG which would possibly execute faster since it does not goes through consensus.
So the whole these time I was keeping in mind that we’re talking about some abstract

"getRandom": () -> (blob) query;

After this (for some reason) we started to mix contexts of this function, trying to look at it from both query and update perspectives. At least it seemed like this from my pov.

In my latest post I’ve made a mistake, thinking that you with @PaulLiu are still discussing ic0.time in query context. Sorry for that. I agree that during an update call the time is constant.

The educated guess you’re making completely fits inside my understanding of the process. Moreover one of my previous messages

describes the same exact moment in the consensus protocol. The block maker node here could cheat a little and propose a timestamp it likes. Since this clock is conceptual, as you say, nobody would argue if it slightly differs from the real one.

The bad thing about not being fluid with English.

3 Likes

Good point @senior.joinu ! It is my bad, I missed the point that the original question was about “query” calls, my discussion above all assumed an “update” call context. Sorry for the confusion caused.

Query calls are not allowed to invoke functions that are specified as update calls. Since raw_rand is a method of the management canister, and all of management methods are update calls, trying to call raw_rand in a query context will trap.

Calling ic0.time() on the other hand works fine in both query and update context.

3 Likes