Open cocreature opened 3 years ago
Two more ideas proposed by @bame-da:
createAndExercise
solution, you would also have to deploy those commands (although you could potentially do it in one API call) but it avoids the two extra nodes.Note that Daml script dumps only reconstruct the root events of a transaction tree into Daml script commands. I.e. the example in the issue description above results in the following Daml script dump:
dump : Parties -> Script ()
dump Parties{..} = do
t1_1_0 <- submit alice_0 do
createCmd Main.T1 with
p = alice_0
tree <- submitTree alice_0 do
exerciseCmd t1_1_0 Main.Create with
p$u0027 = bob_0
pure ()
In this case the ordering of creates and exercises in child events do not pose an issue and the generated Daml script dump correctly reproduces the history. (Apart from the bug in decoding p'
as p$u0027
)
However, the issue is valid. Using exerciseByKeyCmd
it is possible to construct the ordering issue in the root events. Take the following Daml script:
{-# LANGUAGE ApplicativeDo #-}
module Main where
import Daml.Script
template ContractA
with
owner : Party
where
signatory owner
key owner : Party
maintainer key
controller owner can
ArchiveB : ()
do
Some b <- lookupByKey @ContractB owner
archive b
template ContractB
with
owner : Party
where
signatory owner
key owner : Party
maintainer key
setup : Script ()
setup = script do
alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
submit alice do
_ <- createCmd ContractA with owner = alice
_ <- createCmd ContractB with owner = alice
exerciseByKeyCmd @ContractA alice ArchiveB
pure ()
pure ()
Note that the ArchiveB
choice requires ContractB
to be instantiated. However, Daml script dump as of https://github.com/digital-asset/daml/pull/9150#discussion_r595366589 will incorrectly reconstruct this as a createAndExercise
as follows:
dump : Parties -> Script ()
dump Parties{..} = do
tree <- submitTree alice_0 do
createAndExerciseCmd
Main.ContractA with
owner = alice_0
Main.ArchiveB
createCmd Main.ContractB with
owner = alice_0
pure ()
This will fail as lookupByKey @ContractB owner
will return None
.
Note that Daml script dumps only reconstruct the root events of a transaction tree into Daml script commands.
They reconstruct the roots that you see. Bob does not see the exercise as the root, they only see the exercise, create & create as roots.
Ah, I see, yes using only Bob produces the following dump
dump : Parties -> Script ()
dump Parties{..} = do
tree <- submitTree alice_0 do
createAndExerciseCmd
Main.T2 with
p1 = alice_0
p2 = bob_0
Main.C
createCmd Main.T2 with
p1 = alice_0
p2 = bob_0
pure ()
For things like Daml Script dumps, you want to be able to turn the root commands of a transaction tree into Ledger API commands. This seems easy at first, create -> create command, exercise -> exercise command but it runs into issues once one command references an earlier contract created in the same transaction. You can in some cases translate this into
createAndExercise
but this falls apart if the exercise does not follow the create immediately. Here is a concrete example. Bob does not see the exercise but he seescid <- create
,cid2 <- create
,exercise cid …
which is not possible via the ledger API directly.I see two options for Daml Script dumpsd
createAndExercise
on that but that doesn’t produce the original transaction structure so that’s kind of crappy and it’s also rather confusing.I don’t really like either option but 2 seems slightly better.