Kill daml-foundations directory (#2219)

The only stuff left in there are design documents for contract keys and
the time model. The former is being superceded by making contract keys part
of the ledger model. The latter is out of date and will be replaced by
adding a time model to the ledger model as well.
This commit is contained in:
Martin Huschenbett 2019-07-19 09:21:01 +02:00 committed by GitHub
parent 25fd46b2b2
commit 4c11fc6c79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 0 additions and 2166 deletions

View File

@ -1 +0,0 @@
.vscode/

View File

@ -1,15 +0,0 @@
# Documentation
For the user-facing DAML documentation, see [/docs/](/docs/).
In this directory:
* `daml-contract-keys` contains draft documentation for Contract Keys and Quantities
* `time-model` provides documentation on the time model used by DAML
You can preview any of these locally by:
1. `cd` into the appropriate folder
2. Run `da-doc-preview`
3. Go to <http://localhost:8081>

View File

@ -1,8 +0,0 @@
# Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
load("//bazel_tools:docs.bzl", "da_doc_package")
da_doc_package(
name = "daml-contract-keys-quantities",
)

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
# Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
load("//bazel_tools:docs.bzl", "da_doc_package")
da_doc_package(
name = "time-model",
extra_srcs = ["source/index.rst"],
prepare = '''
# Update version
VERSION="HEAD"
sed "s,__VERSION__,$$VERSION,g" -i $(location source/index.rst)
''',
)

View File

@ -1,340 +0,0 @@
.. Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
.. SPDX-License-Identifier: Apache-2.0
============================
The DA Platform Time Model
============================
*Maintainers*: Ognjen Maric
*Last Updated*: 2018-01-24
*Status*: Draft.
Time plays a dual role in the DA platform:
1. the DAML-encoded business processes may rely on time. For
instance, settlement occurs two days after a trade, options have
expiry dates etc.
2. the platform provides no guarantees that a submitted transaction
will be processed; in particular, transactions can be lost. Thus,
the clients must occasionally resubmit transactions. This can
lead to inadvertent duplication of transactions. To prevent this,
the clients require *finality*: the existence of a time bound
after which a submitted transaction is either confirmed to be
processed or it is known that it will not be processed at
all..
This document provides a higher-level rationale for the current design
of the time model in the platform, taking both of the above roles into
the account. We will start from an unrealistic ideal model, and then
gradually introduce real-world concerns. To keep the descriptions
simple, in the sections before the last one we allow ourselves some
artistic freedom in describing the current platform, conflating
clients and participants, ignoring the delays on the read side, and
ignoring the split of the committer into the commit coordinator and
the sequencer. We repent in the last section.
The Ideal Model
===============
In this model:
1. there exists a global notion of time and the clocks of all
components are perfectly synchronized to the global time, and
2. there are no computation or processing delays.
In this ideal case, it appears natural for the clients to submit their
transactions timestamped with the current time ``t[glob]``. To align
with the current (Apollo) platform, we call this timestamp the *ledger
effective time*, ``LET``. To rule out requests from malicious clients
that might attempt "time-travel", the committer checks (in addition to
validity checks of the transaction against the current ledger) that
.. _ideal check:
::
LET = t[glob]
The transaction results (acceptance/rejection) are immediately
published on the event stream, and the clients achieve finality.
Adding Clock Skews
==================
Let us now consider clock skews (ignoring delays). The local clock of
each system component can now deviate from the true global time. We
assume (still unrealistically!) an upper limit ``Δt'`` on this skew;
two local clocks are then off by at most ``Δt = 2·Δt'``. The system
operation stays the same as above, with one exception; to account for
skews, it would be sensible for the committer to relax the `ideal check`_
to:
.. _`clock skew check`:
::
LET ∈ [t[cmtr] - Δt, t[cmtr] + Δt]
where ``t[cmtr]`` denotes the committer's local time.
However, this relaxation is problematic, as the order given by the
committer-produced sequence of transactions and the order induced by
timestamps need not match anymore. This is particularly problematic if
we have two transactions with a DAML-induced causal ordering (``tx2``
comes after ``tx1`` if ``tx2`` consumes outputs of ``tx1``). This
DAML-causal ordering will necessarily be consistent with the committer
ordering, but not with the timestamp one. [#causaltsexample]_ The
committer must thus check the consistency of DAML-causal with
timestamp ordering explicitly. The DA platform now performs this
check. The committer's active contract store stores a LET timestamp
for each created contract. At every exercise node, the referenced
contract is checked to ensure LET monotonicity.
..
.. todo:: do we want to provide a more well-defined link to the ideal
implementation? I.e., how does a run of this new system map into
the ideal system? This appears to be a non-local criterion
(i.e. not a forward/backward simulation) similar to consistency
definitions in the literature (e.g. linearizability, sequential
consistency). The setup is a bit peculiar, since for
e.g. linearizability we require the existence of some linearization
compatible with the observed events; in Apollo, a linearization is
already given by the committer.
Are there other alternatives that avoid this issue? There are at least
two ways to make the timestamp and committer orders coincide:
1. have the committer choose the ``LET``. However, a LET different
from the submitted one could invalidate a DAML transaction. A
potential solution is to have the parties submit DAML expressions
instead of their evaluations ("eval traces"), together with a
time window in which the evaluation is acceptable for the party.
However, this is unlikely to work well with the current committer
design, where the commit coordinator evaluates the expression
first, and the sequencer then updates the ACS, as the evaluation
could also change between the time of evaluation and time of
sequencer.
2. introduce delayed processing in the committer. The transaction's
``LET`` would be checked at arrival using the `clock skew check`_, but would
not be processed immediately. The committer would remove the
transaction tx from the head of a LET-prioritized queue as soon
as :math:`t[cmtr] > LET[tx] + {\Delta}t`. This would increase the
processing latency. In this model with no delays the throughput
is unaffected. In the real system, the throughput might be
affected if the distribution of transactions' LETs is not
uniform.
Processing and Communication Delays
===================================
Let us now add processing and communication delays on the path from
the client to the committer. [#delaydirection]_ We will again be
unrealistic and assume an upper bound ``δ`` on these delays. To
simplify, we will also ignore clock skews. In this case, a transaction
sent at time ``t`` could reach the committer at any point in time
between ``t`` and ``t + δ``. So the committer relaxes the `ideal check`_
to:
.. _`delays check`:
::
LET ∈ [t[glob] - δ, t[glob]]
Note that this relaxation can cause a disagreement between the
timestamp and DAML-causal orderings just like in the case of only
clock skews.
Double Trouble: Delays and Skews
================================
First, let us consider a system with both clock skews ``Δt`` and
delays ``δ``. The committer check here must be the most permissive
combination of the `clock skew check`_ and `delays check`_, which is:
.. _`combined check`:
::
LET ∈ [t[cmtr] - Δt - δ, t[cmtr] + Δt]
Finally, let us consider a realistic model, where the bounds ``Δt``
and ``δ`` are respected most of the time, but not
always. [#partialsync]_ In particular, ``δ`` can be infinite, modeling
a lost message.
Since the bounds are respected most of the time, the `combined check`_ allows
the acceptance of (contention-free) honest clients' transactions most
of the time. However, when the bounds are violated, even messages from
honest clients can be rejected. Furthermore, in the model where bounds
were always respected, the system satisfied a *wait-free bounded*
progress condition: every client is certain to make progress within a
known, bounded amount of time (since the committer's answer would
arrive within ``δ``). With possibly infinite delays, a client can be
delayed for an infinite amount of time, and the system is no longer
wait-free bounded. In fact, it is not even *wait-free*, which is a
weaker condition requiring the client to progress within some finite,
but not necessarily bounded time. [#lockfree]_
To recover this progress property, we can introduce timeouts. The
client specifies a time-to-live (TTL) for any submitted transaction;
the committer must reject transactions that arrive after ``LET + TTL`` has
expired. The API is effectively changed; instead of an
"accepted/rejected" response for a transaction, we introduce a
"timed-out" response. [#apitimeout]_
There is, however, another obstacle: the client must detect that the
``LET + TTL`` has expired *at the committer*. If the ``Δt`` bound
were always respected, and if there was no delay on the committer ->
client path, the check would simply be ``t[client] > LET + TTL + Δt``. But
``Δt`` is *not* always respected. So we apply a different, two-piece
solution:
1. we must ensure that the order of messages on the committer ->
client path coincides with committer's ordering. That is, the
committer must always send the messages in increasing order of
their processing time at the committer, and the committer -> client
channel must be FIFO.
2. the committer must occasionally announce the timestamps of messages
on the committer -> client channel.
Then, once the client observes a message from the committer whose
timestamp exceeds a transaction's ``LET + TTL``, and no earlier notification
about the transaction outcome has been received, the transaction has
definitely timed out.
If the link from the committer to the client is cut off forever, this
scheme also fails to provide wait-freedom. However, under the
assumption that the communication is possible infinitely often (but
not necessarily constantly; e.g. all odd-numbered messages pass, and
all even-numbered fail), we obtain wait-freedom.
Lastly, to ensure that transactions do not time out when the bounds
are respected, the client should choose a TTL such that
.. _`ttl check`:
::
TTL ≈ δ + Δt
Implementation in Apollo
========================
Finally, we describe more precisely how the previous description
relates to the current platform. The committer is divided into a
commit coordinator and a sequencer. The client actually consists of
the actual client application and the participant node. Then:
1. the delay ``δ`` encompasses the delays between the Ledger API and
the commit coordinator (including the command interpretation and
communication), as well as the pre-commit validation at the commit
coordinator.
2. the transactions do not specify a TTL; instead, they specify an
"end-of-life" time called MRT as
``MRT = LET + TTL``.
MRT stands for "maximum record time". This name is confusing, as we
discuss shortly.
3. the commit coordinator enforces something similar to the `ttl check`_
(``CommitCoordinatorImpl.java/verifyMaxRecordTime``). More precisely,
the check is:
.. _mrt:
::
MRT - LET ∈ [minTTL, maxTTL]
for some constants ``minTTL`` and ``maxTTL``. We have:
``TTL = MRT - LET`` implying ``TTL ≥ minTTL``
If ``minTTL`` is close to ``δ + Δt``, this gives us the `ttl check`_.
This check can help misconfigured clients.
4. the sequencer's mempool acceptance rule
(``TimeConstraintValidator.java/memPoolAcceptanceCheck``) ensures
the `combined check`_. More precisely, it checks whether:
``t[seq] ∈ [LET - Δt, MRT]``
This immediately gives us the second half of the `combined check`_:
``LET ≤ t[seq] + Δt``
Moreover, since ``MRT ≤ LET + maxTTL``, we also have
``LET ≥ t[seq] - maxTTL``
Assuming that ``maxTTL`` is chosen to model ``δ + Δt``, this ensures
the `combined check`_.
5. the block record time provides the "occasional timestamp" that we
required. However, note that a transaction with a given ``MRT`` can
be published in a block with a record time that is higher than the
``MRT``! It is only that *after* a block with a record time ``t`` has
been observed that all the transactions with ``MRT ≤ t`` that have
not been observed yet can be safely regarded as lost. The confusion
is due to the fact that "record time" is used for both blocks and
individual transactions; we thus recommend that the name "MRT" be
changed.
6. finally, the correspondence of timestamp and DAML-based orderings
is ensured by
``MemoryProposedChange.java/verifyPredicatesAreNotBeforeCreation``.
.. [#progress] Another perspective is to look at the platform as
providing a distributed (and thus concurrent) version of a virtual
shared global ledger. With any shared data structure, the *progress
conditions* for operations are important. We'll look at them later.
.. [#causaltsexample] For a simple example of why the causal <->
timestamp order disagreement is problematic, consider two DAML
contracts ``c1`` and ``c2`` such that a party ``P``:
- has a choice on ``c1``, *after* time ``t``, which yields a
contract ``c3``
- has a choice on ``c2`` that can only be performed *before* time
``t``, that requires a contract of a form that ``c3`` matches.
There is then nothing preventing ``P`` from exercising its choice
on ``c1`` with a ``LET`` of ``t + Δt/2``, and then feeding the
resulting ``c3`` into the choice of ``c2``, with a ``LET`` of ``t -
Δt/2`` (recall that we are assuming no delays in this model).
.. [#delaydirection] The delays on in the other direction ("read
path") do not seem to have an interesting effect, at least not
with the current solution to the time problem. We thus ignore them.
.. [#partialsync] This is a form of the standard *partial synchrony*
assumption in the distributed systems literature.
.. [#lockfree] In fact's fact, it is not even *lock-free*, which is a
weaker condition still (at least one client makes progress). Which
is to say that clients can get blocked forever.
.. [#apitimeout] The current Ledger API does not provide such a
response, so it is only a logical construction. It is worth
considering whether we want to expose it.

View File

@ -1,355 +0,0 @@
In [9]: all_transactions()
Out[9]:
[{'_next': 'd90bc378dd130eadd98ab6a6f20fd87c78320ae8b0beae48c049c9cb7ea82f06-0',
'businessIntent': 'cada25bb23befdf402ff30d6eec930c157289553b084173f801a942b0b6c1ed4',
'effectiveAt': '2018-02-01T13:32:14.291219Z',
'events': [{'created': {'arguments': {'operator': '00001'},
'contract': 'd90bc378dd130eadd98ab6a6f20fd87c78320ae8b0beae48c049c9cb7ea82f06-0',
'template': 'onboardEntityMaster_t0@Main_Actor_Onboard_2_8d8b3f4df67d40601d301b8f79ecebc50f18e3712c37b91872d2b77a59206daf'}}],
'id': 'd90bc378dd130eadd98ab6a6f20fd87c78320ae8b0beae48c049c9cb7ea82f06',
'index': 0,
'ledgerProcessId': '9d88a213-74a8-4b7d-8a95-6cde7490a7b4'},
{'_next': '7dee7f7797b672e781180001a5872faf63aade391ff8ba5d1e27b07a400d755b-0',
'businessIntent': '65f840b5a2e74fa25d9ef6760dd47fe6530ac382d702e686325abafce2ad5e6b',
'effectiveAt': '2018-02-01T13:32:14.241219Z',
'events': [{'created': {'arguments': {'maintainer': '00001',
'operator': '00001'},
'contract': '7dee7f7797b672e781180001a5872faf63aade391ff8ba5d1e27b07a400d755b-1',
'template': 'onboardLegalEntity_t1@Main_Entity_LegalEntity_3_789d9b7176c0e44ca938f176229ecd98634a577a6a5e329cd5f8ab9a8780a025'}}],
'id': '7dee7f7797b672e781180001a5872faf63aade391ff8ba5d1e27b07a400d755b',
'index': 0,
'ledgerProcessId': '5f003b61-f39b-4af0-9453-7dcceb0f404d'}]
In [10]: get_blocks(100)
Out[10]:
[{'_next': '00001.7468a85a059bf5502d41f215a754b7a01888175267cc6ffe691f413b13c12cd4-1',
'blockHeight': 0,
'errors': [],
'id': '7468a85a059bf5502d41f215a754b7a01888175267cc6ffe691f413b13c12cd4',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '1970-01-01T00:00:00Z',
'transactions': []},
{'_next': '00001.aaec84c0c9a3e62214c4ae7c01a9a2edcdffb93213785a38c8f8391e58b5ec4b-1',
'blockHeight': 1,
'errors': [],
'id': 'aaec84c0c9a3e62214c4ae7c01a9a2edcdffb93213785a38c8f8391e58b5ec4b',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:02.637Z',
'transactions': []},
{'_next': '00001.59740a10f416e98a5c84047bddb7da6192fe91bdd3d31c98f52ba55e43f37f19-1',
'blockHeight': 2,
'errors': [],
'id': '59740a10f416e98a5c84047bddb7da6192fe91bdd3d31c98f52ba55e43f37f19',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:08.321Z',
'transactions': []},
{'_next': '00001.2235f19a1bed9c02c1ff531dd172710a64b634cffdeed70083a6adfbbc2c8a90-1',
'blockHeight': 3,
'errors': [],
'id': '2235f19a1bed9c02c1ff531dd172710a64b634cffdeed70083a6adfbbc2c8a90',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:13.399Z',
'transactions': []},
{'_next': '00001.45f99efc3254e00e054fb02f294d4ed3aff39c41f81948b10b38d4784583beee-2',
'blockHeight': 4,
'errors': [{'code': 'TRANSACTION_OUT_OF_TIME_WINDOW',
'details': {},
'id': {'application': 'UNKNOWN_APPLICATION',
'command': 'cada25bb23befdf402ff30d6eec930c157289553b084173f801a942b0b6c1ed4',
'party': '00001'},
'parameters': {'bimCommitment': 'cada25bb23befdf402ff30d6eec930c157289553b084173f801a942b0b6c1ed4',
'currentTime': '2018-02-01T13:29:16.899Z',
'ledgerEffectiveTime': '2018-02-01T13:29:10.857221Z',
'lowerBound': '2018-02-01T13:29:09.857221Z',
'maxClockSkewNanos': '1000000000',
'upperBound': '2018-02-01T13:29:12.857221Z'}}],
'id': '45f99efc3254e00e054fb02f294d4ed3aff39c41f81948b10b38d4784583beee',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:17.399Z',
'transactions': []},
{'_next': '00001.7b36ba321d91e947f9b5d09a69a6edf0be40b2e1ca24be71cb5dce1a94eb0e2e-1',
'blockHeight': 5,
'errors': [],
'id': '7b36ba321d91e947f9b5d09a69a6edf0be40b2e1ca24be71cb5dce1a94eb0e2e',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:22.486Z',
'transactions': []},
{'_next': '00001.ac4e10894af1ce48532cbf57ce8075491a2be744b0ab583822dcce48ae800b16-1',
'blockHeight': 6,
'errors': [],
'id': 'ac4e10894af1ce48532cbf57ce8075491a2be744b0ab583822dcce48ae800b16',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:27.511Z',
'transactions': []},
{'_next': '00001.b5792c1fae3ab6234129ce540e1158cfe97a107861aab739f76a0435a82fa692-1',
'blockHeight': 7,
'errors': [],
'id': 'b5792c1fae3ab6234129ce540e1158cfe97a107861aab739f76a0435a82fa692',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:32.536Z',
'transactions': []},
{'_next': '00001.7646eeb985b3a1e19e2bc84b59615087437b47b893ccff2f73ee0750d69dcd14-1',
'blockHeight': 8,
'errors': [],
'id': '7646eeb985b3a1e19e2bc84b59615087437b47b893ccff2f73ee0750d69dcd14',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:37.557Z',
'transactions': []},
{'_next': '00001.b2eec80b52409ab8398ded4463dcd34f3eebaa118353d38453aea147c2fb1a7a-1',
'blockHeight': 9,
'errors': [],
'id': 'b2eec80b52409ab8398ded4463dcd34f3eebaa118353d38453aea147c2fb1a7a',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:42.605Z',
'transactions': []},
{'_next': '00001.296e353ba620c3f5e6e234404c50f4695cd39f890c395ef26d0d4ff47f7c0ac0-1',
'blockHeight': 10,
'errors': [],
'id': '296e353ba620c3f5e6e234404c50f4695cd39f890c395ef26d0d4ff47f7c0ac0',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:47.631Z',
'transactions': []},
{'_next': '00001.7c38c6d88d87885f507b22dccfabd241a7f0e4d6f2aa657ca3898aa02a13477f-1',
'blockHeight': 11,
'errors': [],
'id': '7c38c6d88d87885f507b22dccfabd241a7f0e4d6f2aa657ca3898aa02a13477f',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:52.655Z',
'transactions': []},
{'_next': '00001.9baeaf576976c00485dbae4410279ccf3bfdc36152c5b8264955ab6cfafb2334-1',
'blockHeight': 12,
'errors': [],
'id': '9baeaf576976c00485dbae4410279ccf3bfdc36152c5b8264955ab6cfafb2334',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:29:57.680Z',
'transactions': []},
{'_next': '00001.c22af946e275bfa3b3f685e98e24ac41c991c0cff8c3e70684589ad04b67a731-1',
'blockHeight': 13,
'errors': [],
'id': 'c22af946e275bfa3b3f685e98e24ac41c991c0cff8c3e70684589ad04b67a731',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:02.705Z',
'transactions': []},
{'_next': '00001.daf93553769da604ee7391459d9b67f02582ea9fdf5b6ee522544216398612b3-1',
'blockHeight': 14,
'errors': [],
'id': 'daf93553769da604ee7391459d9b67f02582ea9fdf5b6ee522544216398612b3',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:07.726Z',
'transactions': []},
{'_next': '00001.81fb490d351b4411297d3da0e235656b502d4d68673391c3e426f929be4e328c-1',
'blockHeight': 15,
'errors': [],
'id': '81fb490d351b4411297d3da0e235656b502d4d68673391c3e426f929be4e328c',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:12.745Z',
'transactions': []},
{'_next': '00001.8e33c23b8f76c7742e8c7a540c2ef51ae260765979b1f708d33c8f5fc416506e-1',
'blockHeight': 16,
'errors': [],
'id': '8e33c23b8f76c7742e8c7a540c2ef51ae260765979b1f708d33c8f5fc416506e',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:17.766Z',
'transactions': []},
{'_next': '00001.0757ce8c6cdebd7da87a3a8a620ffd0c042ae24e0a3ef72b5b31b04723bdfce6-1',
'blockHeight': 17,
'errors': [],
'id': '0757ce8c6cdebd7da87a3a8a620ffd0c042ae24e0a3ef72b5b31b04723bdfce6',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:22.800Z',
'transactions': []},
{'_next': '00001.226ea01a1c987b06c34a3df586ce1c310ebc5294a217159231f6c5b9d1e169e8-1',
'blockHeight': 18,
'errors': [],
'id': '226ea01a1c987b06c34a3df586ce1c310ebc5294a217159231f6c5b9d1e169e8',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:27.833Z',
'transactions': []},
{'_next': '00001.5d9e5d7d309fb733e23f0c33340ab6c5d283295b39f3dcebb82340ad79759ef3-1',
'blockHeight': 19,
'errors': [],
'id': '5d9e5d7d309fb733e23f0c33340ab6c5d283295b39f3dcebb82340ad79759ef3',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:32.862Z',
'transactions': []},
{'_next': '00001.1e36616fdda542895bdbf7466dfd0aed85ae577485a0a03f3aafc1d6f97a8e0f-1',
'blockHeight': 20,
'errors': [],
'id': '1e36616fdda542895bdbf7466dfd0aed85ae577485a0a03f3aafc1d6f97a8e0f',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:37.887Z',
'transactions': []},
{'_next': '00001.8ed808871cf05009c28fdb801426c1848d3d6d852dc8070b8b5894a76bf72cc2-1',
'blockHeight': 21,
'errors': [],
'id': '8ed808871cf05009c28fdb801426c1848d3d6d852dc8070b8b5894a76bf72cc2',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:42.911Z',
'transactions': []},
{'_next': '00001.d1be7f26baba9a09bbb6345bc79378995fad465d3a580216ba78f919c7b7f8d5-1',
'blockHeight': 22,
'errors': [],
'id': 'd1be7f26baba9a09bbb6345bc79378995fad465d3a580216ba78f919c7b7f8d5',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:47.936Z',
'transactions': []},
{'_next': '00001.741a34cdde8caa7b567f62e6b287da1313127b0621dbf0c46769a0a1917bde5a-1',
'blockHeight': 23,
'errors': [],
'id': '741a34cdde8caa7b567f62e6b287da1313127b0621dbf0c46769a0a1917bde5a',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:52.961Z',
'transactions': []},
{'_next': '00001.b4cb96a250aeef6e2db6e57e4cf0d5206f6ea75ddc971df1b46904b2145aa0e9-1',
'blockHeight': 24,
'errors': [],
'id': 'b4cb96a250aeef6e2db6e57e4cf0d5206f6ea75ddc971df1b46904b2145aa0e9',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:30:57.985Z',
'transactions': []},
{'_next': '00001.7a6a1620f4569f5eafe895aea78a1b99f7409b8191ecae6981ec8b4dff3908fd-1',
'blockHeight': 25,
'errors': [],
'id': '7a6a1620f4569f5eafe895aea78a1b99f7409b8191ecae6981ec8b4dff3908fd',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:03.012Z',
'transactions': []},
{'_next': '00001.30325a33773840843e3bd54e093ff08f6aa865c67b90d18a97920b0f3dd570dd-1',
'blockHeight': 26,
'errors': [],
'id': '30325a33773840843e3bd54e093ff08f6aa865c67b90d18a97920b0f3dd570dd',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:08.032Z',
'transactions': []},
{'_next': '00001.ab612198904743b21c9300fc43bc61b706acd66027140dcd82ed966c39b1d7bd-1',
'blockHeight': 27,
'errors': [],
'id': 'ab612198904743b21c9300fc43bc61b706acd66027140dcd82ed966c39b1d7bd',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:13.057Z',
'transactions': []},
{'_next': '00001.b174eac6be67658fa2def9f9e3ef3d990507c4f229175bf5f4e9ab2139a75b32-1',
'blockHeight': 28,
'errors': [],
'id': 'b174eac6be67658fa2def9f9e3ef3d990507c4f229175bf5f4e9ab2139a75b32',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:18.085Z',
'transactions': []},
{'_next': '00001.bfd642d0bbd898bd73a2e76294a48e6ed2a86c831152b6860d75a4459566eb5c-1',
'blockHeight': 29,
'errors': [],
'id': 'bfd642d0bbd898bd73a2e76294a48e6ed2a86c831152b6860d75a4459566eb5c',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:23.111Z',
'transactions': []},
{'_next': '00001.7901da49dc4e01d32368927e170f1fb6ef0b3ec65f48682e09d5011c10e758e2-1',
'blockHeight': 30,
'errors': [],
'id': '7901da49dc4e01d32368927e170f1fb6ef0b3ec65f48682e09d5011c10e758e2',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:28.137Z',
'transactions': []},
{'_next': '00001.110a57d4a09127c8b38eed576c3621ff8c5e6a5a3b056c6a1694855170401305-1',
'blockHeight': 31,
'errors': [],
'id': '110a57d4a09127c8b38eed576c3621ff8c5e6a5a3b056c6a1694855170401305',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:33.156Z',
'transactions': []},
{'_next': '00001.d0a451a848009f0596b1a797cfcf5fb00b9912112fa59a61c7a863d09d94941a-1',
'blockHeight': 32,
'errors': [],
'id': 'd0a451a848009f0596b1a797cfcf5fb00b9912112fa59a61c7a863d09d94941a',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:38.182Z',
'transactions': []},
{'_next': '00001.6b08fc8b695497c9f74d417e767b918e4d7344d9a82173d41c1f9ec80322a00e-1',
'blockHeight': 33,
'errors': [],
'id': '6b08fc8b695497c9f74d417e767b918e4d7344d9a82173d41c1f9ec80322a00e',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:43.215Z',
'transactions': []},
{'_next': '00001.f5073352c608b9c082faa2d72949ec79d7160d9e34d3b2fa2248932aba500ab3-1',
'blockHeight': 34,
'errors': [],
'id': 'f5073352c608b9c082faa2d72949ec79d7160d9e34d3b2fa2248932aba500ab3',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:48.239Z',
'transactions': []},
{'_next': '00001.2281e86d934b2b7a3dcec2bf6893cb3e4efd6c47e794abe251034c1452ac8002-1',
'blockHeight': 35,
'errors': [],
'id': '2281e86d934b2b7a3dcec2bf6893cb3e4efd6c47e794abe251034c1452ac8002',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:53.268Z',
'transactions': []},
{'_next': '00001.bb848d15ef72cb38836f86ae2c0a269509b42c103db68fa46c71b88c68db8e8e-1',
'blockHeight': 36,
'errors': [],
'id': 'bb848d15ef72cb38836f86ae2c0a269509b42c103db68fa46c71b88c68db8e8e',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:31:58.291Z',
'transactions': []},
{'_next': '00001.9f5a21dd73af19fb244be26d3e54afd204eba282dc1fba5919581194bbba2862-1',
'blockHeight': 37,
'errors': [],
'id': '9f5a21dd73af19fb244be26d3e54afd204eba282dc1fba5919581194bbba2862',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:32:03.310Z',
'transactions': []},
{'_next': '00001.bc6bdbe9ffdd02e9926b7541dd895effa2ef478fab09117dcb40b208282278c0-1',
'blockHeight': 38,
'errors': [],
'id': 'bc6bdbe9ffdd02e9926b7541dd895effa2ef478fab09117dcb40b208282278c0',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:32:08.333Z',
'transactions': []},
{'_next': '00001.ebce05253acece55ce1352753eb5e268f642c58a9641b77076e39595cb6ef589-1',
'blockHeight': 39,
'errors': [],
'id': 'ebce05253acece55ce1352753eb5e268f642c58a9641b77076e39595cb6ef589',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:32:13.360Z',
'transactions': []},
{'_next': '00001.18979ea5fb579a710e767184c6c26b25f96ba0009ff355e2526e03d9eeb4a562-2',
'blockHeight': 40,
'errors': [],
'id': '18979ea5fb579a710e767184c6c26b25f96ba0009ff355e2526e03d9eeb4a562',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:32:14.850Z',
'transactions': [{'_next': 'd90bc378dd130eadd98ab6a6f20fd87c78320ae8b0beae48c049c9cb7ea82f06-0',
'businessIntent': 'cada25bb23befdf402ff30d6eec930c157289553b084173f801a942b0b6c1ed4',
'effectiveAt': '2018-02-01T13:32:14.291219Z',
'events': [{'created': {'arguments': {'operator': '00001'},
'contract': 'd90bc378dd130eadd98ab6a6f20fd87c78320ae8b0beae48c049c9cb7ea82f06-0',
'template': 'onboardEntityMaster_t0@Main_Actor_Onboard_2_8d8b3f4df67d40601d301b8f79ecebc50f18e3712c37b91872d2b77a59206daf'}}],
'id': 'd90bc378dd130eadd98ab6a6f20fd87c78320ae8b0beae48c049c9cb7ea82f06',
'index': 0,
'ledgerProcessId': '9d88a213-74a8-4b7d-8a95-6cde7490a7b4'}]},
{'_next': '00001.27716f97c2c75e2fd21eed3c6b1044ff7ca4f2cdb6fc6c9cb99991afff6a0b8e-2',
'blockHeight': 41,
'errors': [],
'id': '27716f97c2c75e2fd21eed3c6b1044ff7ca4f2cdb6fc6c9cb99991afff6a0b8e',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:32:18.382Z',
'transactions': [{'_next': '7dee7f7797b672e781180001a5872faf63aade391ff8ba5d1e27b07a400d755b-0',
'businessIntent': '65f840b5a2e74fa25d9ef6760dd47fe6530ac382d702e686325abafce2ad5e6b',
'effectiveAt': '2018-02-01T13:32:14.241219Z',
'events': [{'created': {'arguments': {'maintainer': '00001',
'operator': '00001'},
'contract': '7dee7f7797b672e781180001a5872faf63aade391ff8ba5d1e27b07a400d755b-1',
'template': 'onboardLegalEntity_t1@Main_Entity_LegalEntity_3_789d9b7176c0e44ca938f176229ecd98634a577a6a5e329cd5f8ab9a8780a025'}}],
'id': '7dee7f7797b672e781180001a5872faf63aade391ff8ba5d1e27b07a400d755b',
'index': 0,
'ledgerProcessId': '5f003b61-f39b-4af0-9453-7dcceb0f404d'}]},
{'_next': '00001.0a51376772075bf3201d4b7886ebd43d706ae3c75b95dd6178dd16bae92cb284-1',
'blockHeight': 42,
'errors': [],
'id': '0a51376772075bf3201d4b7886ebd43d706ae3c75b95dd6178dd16bae92cb284',
'ledgerConfiguration': {'maxTtl': 120000000000, 'minTtl': 2000000000},
'recordedAt': '2018-02-01T13:32:23.407Z',
'transactions': []},