Skip to content

Wall-clock time and OS entropy exposed to guest break determinism (time_now / random_bytes) #3099

Description

@chefsale

Summary

Two host functions inject per-node nondeterminism into guest execution:

  • time_now calls SystemTime::now() (wall clock).
  • random_bytes pulls from rand::thread_rng() (OS entropy).

In a replicated state machine every node must derive identical state from identical inputs. Both of these let two honest nodes running the same call observe different values, which can cause state divergence.

Severity: High (determinism in a replicated state machine).

Location

  • crates/runtime/src/logic/host_functions/utility.rstime_now (SystemTime::now().duration_since(UNIX_EPOCH)) and random_bytes (rand::thread_rng().fill_bytes(...)).
  • Import wiring: crates/runtime/src/logic/imports.rs (fn random_bytes(ptr: u64);, fn time_now(ptr: u64);).

Details

The fix direction is fairly clear, but it is a guest-observable semantics change, which is why it was deferred for explicit sign-off rather than bundled with the mechanical safety fixes.

Possible solutions

  1. time_now → derive from the HLC.
    Use the hybrid logical clock instead of the wall clock. calimero_storage::env::hlc_timestamp() already exists and is used by persist_root_state (see the hlc_to_nanos helper there). This changes what "now" means for every guest but makes it deterministic across nodes.

  2. random_bytes → seed a deterministic RNG from a context-deterministic source.
    Replace OS entropy with a deterministic RNG (e.g. ChaCha) seeded from context_id + executor_public_key + a per-call counter (all available on VMLogic/VMContext). Reproducible across nodes — which is the point for consensus, but a footgun for apps that (mis)use it for secrets/nonces.

    • Consider whether to expose a separate, explicitly non-deterministic entropy escape hatch for the rare legitimate case, so the default stays safe.

Open questions

  • Is determinism required for these functions in the current execution model, or are there call sites where real time/entropy is intentional and non-consensus?
  • Exact seed derivation for the deterministic RNG (inputs + per-call counter scheme).
  • Whether a separate insecure-random API is desirable.

Context

Split out from the host-function safety batch in #3097 (the four low-risk fixes landed there). Deferred because it changes guest-observable semantics.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions