Why is record time for transactions not exposed on the Ledger API

The SDK docs say that every DAML transaction has a “ledger effective time” and a “record time”. The gRPC API provides an effective_at field, which according to its docs shows the ledger effective time. But there is no such field for the record time. Why?

Probably because no one used it so far.

We could add it, but I don’t see why a client application would care about the record time. Do you have such a use case?

I do, I want to simplify running distributed scenarios in Canton. Take two transactions tx1 and tx2 where tx2 uses some contracts produced by tx1. The transactions are to be submitted over participants p1 and p2 respectively. Before submitting tx2 to p2, I need to ensure that p2 has seen tx1. To even know that p2 is supposed to see tx1, I need to know the distributed topology at the exact time where tx1 is committed, hence, I need to know the record time of tx1.

Out of curiosity, what are the use cases for letting the applications know the effective time?

Sorry I did not quite understand your use case.

It looks like you want to wait for the completion of tx1 on p1, from which you will get record time associated with the commit of tx1. Given that record time, how exactly would you determine whether p2 can see tx1?

There are also a few things to note:

  • The record time is measured using a different clock than the local clock of the machine running the ledger API client application. You should be careful when comparing your local clock to the record time.
  • We don’t make any guarantees on the record time. For example, some ledgers will set record_time := ledger_time and use different mechanisms to make sure that the submitted ledger_time “is close enough to actual time”. As such, the record time might not even be monotonically increasing.

To your question:

  1. From tx1, I can figure out all witnesses of that transaction
  2. From the involved parties, I can figure out the involved participants

Both of these steps also require some Canton-specific functionalities. In particular, figuring out all parties connected to the domain, and figuring what their participants are. Furthermore, both of these things can be dynamic (e.g., parties can be added to participants, participants can connect/disconnect from domains). To be free of race conditions, I need to look at the party-participant topology as it was at the record time of tx1.

Ah, I see. And how would you get the party-participant topology at a specific record time? The current ledger API is limited here: it only allows you to query the current parties, it does not tell you when a party was added to a participant, and it is not ready for multi-domain ledgers in general.

Does Canton have some custom API for querying the topology at a given time?

Yes, it’s at the moment a custom Canton functionality; search for parties.list here:


If a party is added to a participant, wouldn’t all its history be transferred to that participant as well? Otherwise the party has to know which commands it can send to which participant, which seems rather inconvenient. I’m curious to learn about the use cases canton strives to support with this.

I think the Transaction Service (in tree mode) should return all information that is needed to verify that a Party’s view of the ledger conforms to the DAML Ledger Model. Given that the Time Model explicitly mentions Record Time, we should therefore include it.

Ed: I see @Robert_Autenrieth has already opened issue #6495, thanks.


Ideally, yes; though we’ve only started working on this and in the first iteration this process will be completely offline (there are tricky synchronization issues otherwise), and will just move the ACS, not the full history. But we have full support for removing parties right now :smiley: so the case described above is a potential race condition (some of our tests break, for examle).

Additionally, once we have pruning, the apps will have to be able to cope with lack of history anyways (it’s possible that the transaction stream gets pruned “from under their feet”, and they have to re-initialize from a recent ACS snapshot). For command ID tracking, we don’t currently support cross-participant de-dup, but it will come at some point (though I assume the guarantees you get will be fewer).