Skip to content

Commit

Permalink
Add time model documentation (digital-asset#6705)
Browse files Browse the repository at this point in the history
* Update existing docs, removing references to old time model
* Add detailed time model docs
* Rename ledger effective time to ledger time

CHANGELOG_BEGIN
CHANGELOG_END
  • Loading branch information
rautenrieth-da authored Jul 17, 2020
1 parent 7ce9748 commit 1074736
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 13 deletions.
1 change: 1 addition & 0 deletions docs/source/app-dev/app-arch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,4 @@ How is this used in practice?
- Set ``min_ledger_time_abs`` or ``min_ledger_time_rel`` if the duration of command interpretation and transmission is likely to take a long time relative to the tolerance interval set by the ledger.
- In some corner cases, the participant node may be unable to determine a suitable ledger time by itself. If you get an error that no ledger time could be found, check whether you have contention on any contract referenced by your command or whether the referenced contracts are sensitive to small changes of ``getTime``.

For details, see :ref:`Background concepts - time <time>`.
2 changes: 1 addition & 1 deletion docs/source/app-dev/services.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ Ledger configuration service

Use the **ledger configuration service** to subscribe to changes in ledger configuration.

This configuration includes maximum and minimum values for the difference in Ledger Effective Time and Maximum Record Time (see `Time Service <#time-service>`__ for details of these).
This configuration includes the maximum command deduplication time (see `Command Deduplication <#command-submission-service-deduplication>`__ for details).

For full details, see :ref:`the proto documentation for the service <com.daml.ledger.api.v1.LedgerConfigurationService>`.

Expand Down
121 changes: 121 additions & 0 deletions docs/source/concepts/time.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
.. Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
.. SPDX-License-Identifier: Apache-2.0
.. _time:

Time
####

The DAML language contains a function :ref:`getTime <daml-ref-gettime>` which returns the “current time”.
However, the notion of time comes with a lot of problems in a distributed setting.

This document describes the detailed semantics of time on DAML ledgers,
centered around the two timestamps assigned to each transaction:
the *ledger time* ``lt_TX`` and the *record time* ``rt_TX``.


.. _ledger_time:

Ledger time
***********

The *ledger time* ``lt_TX`` is a property of a transaction.
It is a timestamp that defines the value of all :ref:`getTime <daml-ref-gettime>` calls in the given transaction,
and has microsecond resolution.
The ledger time is assigned by the submitting participant as part of the DAML command interpretation.


.. _record-time:

Record time
***********

The *record time* ``rt_TX`` is another property of a transaction.
It is timestamp with microsecond resolution,
and is assigned by the ledger when the transaction is recorded on the ledger.

The record time should be an intuitive representation of "real time",
but the DAML ledger model does not prescribe how exactly the record time is assigned.
Each ledger implementation might use a different way of representing time in a distributed setting -
for details, contact your ledger operator.


.. _time_guarantees:

Guarantees
**********

The ledger time of valid transaction ``TX`` must fullfil the following rules:

#. **Causal monotonicity**: for any action (create, exercise, fetch, lookup) in ``TX``
on a contract ``C``, ``lt_TX >= lt_C``,
where ``lt_C`` is the ledger time of the transaction that created ``C``.

#. **Bounded skew**: ``rt_TX - skew_min <= lt_TX <= rt_TX + skew_max``,
where ``skew_min`` and ``skew_max`` are parameters defined by the ledger.

Apart from that, no other guarantees are given on the ledger time.
In particular, neither the ledger time nor the record time need to be monotonically increasing.

Time has therefore to be considered slightly fuzzy in DAML, with the fuzziness depending on the skew parameters.
DAML applications should not interpret the value returned by :ref:`getTime <daml-ref-gettime>` as a precise timestamp.


.. _ledger-time-model:

Ledger time model
*****************

The *ledger time model* is the set of parameters used in the assignment and validation of ledger time.
It consists of the following:

#. ``skew_min`` and ``skew_max``, the bounds on the difference between ``lt_TX`` and ``rt_TX``.

#. ``transaction_latency``, the average duration from the time a transaction is submitted from a participant to the ledger
until the transaction is recorded.
This value is used by the participant to account for latency when submitting transactions to the ledger:
transactions are submitted slightly ahead of their ledger time, with the intention that they arrive at ``lt_TX == rt_TX``.

The ledger time model is part of the ledger configuration and can be changed by ledger operators through the
:ref:`SetTimeModel <com.daml.ledger.api.v1.admin.SetTimeModelRequest>` config management API.


.. _assigning-ledger-time:

Assigning ledger time
*********************

The ledger time is assigned automatically by the participant.
In most cases, DAML applications will not need to worry about ledger time and record time at all.

For reference, this section describes the details of how the ledger time is currently assigned.
The algorithm is not part of the definition of time in DAML, and may change in the future.

#. When submitting commands over the ledger API,
users can optionally specify a ``min_ledger_time_rel`` or ``min_ledger_time_abs`` argument.
This defines a lower bound for the ledger time in relative and absolute terms, respectively.

#. The ledger time is set to the highest of the following values:

#. ``max(lt_C_1, ..., lt_C_n)``, the maximum ledger time of all contracts used by the given transaction
#. ``t_p``, the local time on the participant
#. ``t_p + min_ledger_time_rel``, if ``min_ledger_time_rel`` is given
#. ``min_ledger_time_abs``, if ``min_ledger_time_abs`` is given

#. Since the set of commands used by given transaction can depend on the chosen time,
the above process might need to be repeated until a suitable ledger time is found.

#. If no suitable ledger time is found after 3 iterations, the submission is rejected.
This can happen if there is contention around a contract,
or if the transaction uses a very fine-grained control flow based on time.

#. At this point, the ledger time may lie in the future (e.g., if a large value for ``min_ledger_time_rel`` was given).
The participant waits until ``lt_TX - transaction_latency`` before it submits the transaction to the ledger -
the intention is that the transaction is record at ``lt_TX == rt_TX``.

Use the parameters ``min_ledger_time_rel`` and ``min_ledger_time_abs`` if you expect that
command interpretation will take a considerate amount of time, such that by
the time the resulting transaction is submitted to the ledger, its assigned ledger time is not valid anymore.
Note that these parameters can only make sure that the transaction arrives roughly at ``rt_TX`` at the ledger.
If a subsequent validation on the ledger takes longer than ``skew_max``,
the transaction will still be rejected and you'll have to ask your ledger operator to increase the ``skew_max`` time model parameter.
16 changes: 9 additions & 7 deletions docs/source/daml/intro/5_Restrictions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,28 +78,30 @@ There's also quite a lot going on inside the ``do`` block of the ``Redeem`` choi
Time on DAML ledgers
--------------------

Each transaction on a DAML ledger has two timestamps called the *ledger effective time (LET)* and the *record time (RT)*. The ledger effective time is set by the submitter of a transaction, the record time is set by the consensus protocol.
Each transaction on a DAML ledger has two timestamps called the *ledger time (LT)* and the *record time (RT)*. The ledger time is set by the participant, the record time is set by the ledger.

Each DAML ledger has a policy on the allowed difference between LET and RT called the *skew*. The submitter has to take a good guess at what the record time will be. If it's too far off, the transaction will be rejected.
Each DAML ledger has a policy on the allowed difference between LT and RT called the *skew*. The participant has to take a good guess at what the record time will be. If it's too far off, the transaction will be rejected.

``getTime`` is an action that gets the LET from the ledger. In the above example, that time is taken apart into day of week and hour of day using standard library functions from ``DA.Date`` and ``DA.Time``. The hour of the day is checked to be in the range from 8 to 18.
``getTime`` is an action that gets the LT from the ledger. In the above example, that time is taken apart into day of week and hour of day using standard library functions from ``DA.Date`` and ``DA.Time``. The hour of the day is checked to be in the range from 8 to 18.

Suppose now that the ledger had a skew of 10 seconds, but a submission took less than 4 seconds to commit. At 18:00:05, Alice could submit a transaction with a LET of 17:59:59 to redeem an Iou. It would be a valid transaction and be committed successfully as ``getTime`` will return 17:59:59 so ``hrs == 17``. Since RT will be before 18:00:09, ``LET - RT < 10 seconds`` and the transaction won't be rejected.
Consider the following example: Suppose that the ledger had a skew of 10 seconds. At 17:59:55, Alice submits a transaction to redeem an Iou. One second later, the transaction is assigned a LET of 17:59:56, but then takes 10 seconds to commit and is recorded on the ledger at 18:00:06. Even though it was committed after business hours, it would be a valid transaction and be committed successfully as ``getTime`` will return 17:59:56 so ``hrs == 17``. Since the RT is 18:00:06, ``LT - RT <= 10 seconds`` and the transaction won't be rejected.

Time therefore has to be considered slightly fuzzy in DAML, with the fuzziness depending on the skew parameter.

For details, see :ref:`Background concepts - time <time>`.

Time in scenarios
~~~~~~~~~~~~~~~~~

In scenarios, record and ledger effective time are always equal. You can set them using the following functions:
In scenarios, record and ledger time are always equal. You can set them using the following functions:

- ``passToDate``, which takes a date and sets the time to midnight (UTC) of that date
- ``pass``, which takes a ``RelTime`` (a relative time) and moves the ledger by that much

Time on ledgers
~~~~~~~~~~~~~~~~~

On a distributed DAML ledger, there are no guarantees that ledger effective time or relative time are strictly increasing. The only guarantee is that ledger effective time is increasing with causality. That is, if a transaction ``TX2`` depends on a transaction ``TX1``, then the ledger enforces that the LET of ``TX2`` is greater than or equal to that of ``TX1``:
On a distributed DAML ledger, there are no guarantees that ledger time or record time are strictly increasing. The only guarantee is that ledger time is increasing with causality. That is, if a transaction ``TX2`` depends on a transaction ``TX1``, then the ledger enforces that the LT of ``TX2`` is greater than or equal to that of ``TX1``:

.. literalinclude:: daml/daml-intro-5/Restrictions.daml
:language: daml
Expand All @@ -126,7 +128,7 @@ However, the expressions you've seen that used the ``<-`` notation are not like
now <- getTime
You cannot work out the value of ``now`` based on any variable in scope. To put it another way, there is no expression ``expr`` that you could put on the right hand side of ``now = expr``. To get the ledger effective time, you must be in the context of a submitted transaction, and then look at that context.
You cannot work out the value of ``now`` based on any variable in scope. To put it another way, there is no expression ``expr`` that you could put on the right hand side of ``now = expr``. To get the ledger time, you must be in the context of a submitted transaction, and then look at that context.

Similarly, you've come across ``fetch``. If you have ``cid : ContractId Account`` in scope and you come across the expression ``fetch cid``, you can't evaluate that to an ``Account`` so you can't write ``account = fetch cid``. To do so, you'd have to have a ledger you can look that contract ID up on.

Expand Down
2 changes: 1 addition & 1 deletion docs/source/daml/reference/structure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ The update expressions are:
``assert (amount > 0)``

:ref:`getTime <daml-ref-gettime>`
Gets the ledger effective time. Usually used to restrict when a choice can be exercised.
Gets the ledger time. Usually used to restrict when a choice can be exercised.

``currentTime <- getTime``

Expand Down
2 changes: 1 addition & 1 deletion docs/source/daml/reference/updates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ getTime
currentTime <- getTime
- ``getTime`` keyword.
- Gets the ledger effective time. (You will usually want to immediately bind it to a variable in order to be able to access the value.)
- Gets the ledger time. (You will usually want to immediately bind it to a variable in order to be able to access the value.)
- Used to restrict when a choice can be made. For example, with an ``assert`` that the time is later than a certain time.

Here's an example of a choice that uses a check on the current time:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/daml/reference/working-with.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ DAML has these built-in functions for working with time:
- ``subTime``: subtracts one time from another. Returns the ``RelTime`` difference between ``time1`` and ``time2``.
- ``addRelTime``: add times. Takes a ``Time`` and ``RelTime`` and adds the ``RelTime`` to the ``Time``.
- ``days``, ``hours``, ``minutes``, ``seconds``: constructs a ``RelTime`` of the specified length.
- ``pass``: (in :doc:`scenario tests <../testing-scenarios>` only) use ``pass : RelTime -> Scenario Time`` to advance the ledger effective time by the argument amount. Returns the new time.
- ``pass``: (in :doc:`scenario tests <../testing-scenarios>` only) use ``pass : RelTime -> Scenario Time`` to advance the ledger time by the argument amount. Returns the new time.

Working with numbers
********************
Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ DAML SDK documentation
concepts/glossary
concepts/ledger-model/index
concepts/identity-and-package-management
concepts/time

.. toctree::
:titlesonly:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/support/release-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ Impact and Migration
>>>>>>>>>>>>>>>>>>>>
Old applications will continue running against new ledgers, but
ledger effective time and maximum record time set on submissions will
ledger time and maximum record time set on submissions will
be ignored. As soon as the client-side language bindings or compiled
gRPC services are updated, the fields will need to be removed as they
are no longer part of the API specification.
Expand Down
2 changes: 1 addition & 1 deletion ledger/participant-state/protobuf/ledger_configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ message LedgerTimeModel
*since version 1*

Defines the ledger time model, which governs the rules for acceptable
ledger effective time and maximum record time parameters that are part
ledger time and maximum record time parameters that are part
of transaction submission.

As of version 1, these fields are included:
Expand Down

0 comments on commit 1074736

Please sign in to comment.