Skip to content

Conversation

eddyashton
Copy link
Member

No longer need to separate these - all code can call standard library functions to access time.

@eddyashton eddyashton requested a review from a team as a code owner July 30, 2025 11:46
@achamayou
Copy link
Member

achamayou commented Aug 4, 2025

I think it's arguably useful to preserve the shim, and expose a single time at least in JS execution sandboxes.

Edit: thought about this some more, and I think this is best done as a get_untrusted_host_tx_start_time() C++ API, which QuickJS then calls, and which effectively sets the time on first use per tx. I think we could even arguably save that to an appropriate map, because a tx calling this probably cares about reproducibility, but then there's a decision to be made about private vs public. This is probably a separate feature though.

@eddyashton
Copy link
Member Author

eddyashton commented Aug 11, 2025

I think it's arguably useful to preserve the shim, and expose a single time at least in JS execution sandboxes.

Edit: thought about this some more, and I think this is best done as a get_untrusted_host_tx_start_time() C++ API, which QuickJS then calls, and which effectively sets the time on first use per tx. I think we could even arguably save that to an appropriate map, because a tx calling this probably cares about reproducibility, but then there's a decision to be made about private vs public. This is probably a separate feature though.

While this is a plausibly useful feature, it is not the semantics we previously offered - this would be a new feature. The JS sandboxes didn't get a fixed-at-transaction-start time. Calling Date() returned either Jan 1st 1970, or the latest value from get_enclave_time(), depending on whether they'd called ccf.enableUntrustedDateTime(true)*. The former is constant, but unrelated to the transaction, and the latter could vary during transaction execution (at low granularity, if execution took long enough, via a uv_timer task).

This PR is aiming to simply remove the concept of "untrusted host time", since it was SGX-specific. This also provides parity between C++ and JS - their natural builtin time-fetching APIs work lift-and-shift style. I think this is the right place for us to be, and any app that needs deterministic fixed timestamps for reproducibility can do so themselves?

* TODO - I need to deprecate, and document the deprecation of, this API.

@achamayou
Copy link
Member

@eddyashton I agree it's a new feature, but I think it's one to consider for applications where replayability is important. There's a range of options we can provide:

  1. Time of the last signature
  2. Host time at the beginning of the transition, guaranteed to be monotonic

Across a few API choices:

  1. Mandatory, you need to call get_unsafe_host_time if you don't want those properties
  2. Optional, you need to call get_monotonic_ledger_time if you want those properties
  3. Optional, but lift-and-shift in JS: set monotonic_ledger_date and new Date always does that in a sandbox, even for dependencies/libraries

With one more dimension:

  1. You can save the time in the table of your choice
  2. There is a public time table for all transactions that use time, where CCF saves time

The monotonicity has non trivial implications on concurrency control, by the way.

@achamayou achamayou enabled auto-merge August 26, 2025 08:46
@achamayou achamayou added this pull request to the merge queue Aug 26, 2025
Merged via the queue into microsoft:main with commit 6657caa Aug 26, 2025
18 checks passed
@achamayou achamayou deleted the no_more_time_hacks branch August 26, 2025 10:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants