Any strategies for this? Any way form my code to switch on an environment var?
Maybe query network time…
There is only one Time.now() function. Are there system shared functions I can get to like msg.time or something like that?
What msg.time means? the transactions signature created time?
Time.now() is the moment executing the canister function, I think it’s sufficient for most situations.
The IC does not provide any such functionality. Unfortunately, “system time” has no well-defined meaning in a distributed system. Plus, execution on the IC has to be deterministic across replicas. Hence, Time.now is the closest to “real” time that the platform can provide.
Running “locally” does not change that, since it is supposed to maintain all observable properties of the real network.
So why then is it not doing so? When I call Time.now() from my motoko code on my local replica it errors out with the message in the title. Maybe this just needs to be implemented as a switch in dfx? Or in the Prim library shim for local replicas? It makes testing canisters locally very difficults. I was using it as a bit of chaos in a Hash calc so it is easy to route around for now with a nonce, but in the long run I’d like a bit less predictability.
Actually, can you clarify what you mean by running “locally”?
Time.now() probably fails when run in the interpreter (probably with an ugly stacktrace), but should work on the emulator, local replica and full network.
I don’t know of any way to programmatically detect whether the code is running in the interpreter or a replica - perhaps we should add one. But the interpreter is really not meant for running production code, even for testing purposes. There are too many aspects of the IC that are not yet fully implemented in the interpreter (such as cycle management, state rollback on trap, etc).
Ah, sorry, I think I misunderstood your question. By “running locally”, do you mean compiling with
--no-system-api? Well, as the name indicates, that does not give access to any system functionality, and instead creates a pure Wasm module with no dependencies.
Ahhh…yes… you are right. This is failing while running tests:
$(shell vessel bin)/moc $(shell vessel sources) -wasi-system-api -o Test.wasm Test.mo && wasmtime Test.wasm
Any strategy for faking a time here? Or creating a mock?
Hah! I actually forget about the wasi backend - I think we should be able to mock something for time there, but there’s lots of other stuff that doesn’t work on the wasi target (like actors).
A legitimate use of the wasi target (for now) is for testing libraries of non-IC functionality such as basic data structure libraries. That’s what bits of the motoko-base library are tested on.