Hi there,
In the release notes for 1.14.0 Release of Daml Connect 1.14.0 it outlines that “use of divulged contracts during transaction interpretation(/submission) is being deprecated and removed in a phased manner”. What is meant by “during transaction interpretation(/submission)”? What is a concrete example of using a divulged contract during transaction interpretation?
The minimal example is something like the following
module Main where
import Daml.Script
template T
with
p : Party
where
signatory p
template Fetcher
with
sig : Party
obs : Party
where
signatory sig
observer obs
nonconsuming choice Fetch : T
with
cid : ContractId T
controller obs
do fetch cid
test = script do
p1 <- allocateParty "p1"
p2 <- allocateParty "p2"
cid <- submit p1 $ createCmd (T p1)
fetcher <- submit p1 $ createCmd (Fetcher p1 p2)
divulger <- submit p2 $ createCmd (Fetcher p2 p1)
submitMustFail p2 $ exerciseCmd fetcher (Fetch cid)
submit p1 $ exerciseCmd divulger (Fetch cid)
submit p2 $ exerciseCmd fetcher (Fetch cid)
pure ()
Let’s walk through this:
- There is a contract
cid
wherep1
is the only stakeholder. - There is a contract
fetcher
which is signed by p1 and has p2 as an observer. That contract allowsp2
to fetch a contract withp1
’s authorization. - However, if you try that, you’ll get an error saying that the contract is not visible to the submitter.
- Now, we create a
divulger
contract which is the same asfetcher
but with the roles switched. -
p1
can execute theFetch
here since they are a stakeholder oncid
. Becausep2
is a signatory on the contract they see the exercise so they also see the fetch meaning the contract is divulged to them. So far, everything works as it should and none of this is deprecated. - Currently, step 5 permanently changes things such that step 3 will now succeed because
p2
has seen the contract once in step 5. This is the part that is deprecated.
This might all sound a bit confusing so let me try to provide an explanation of what works rather than what doesn’t:
For a transaction to not rely on divulgence of previous transactions, all contracts fetched, exercised, … in the current transaction must have one or more stakeholders in the union of actAs and readAs parties of the sumission.
Thanks for that example. I think I’m understanding this now. Is there any deprecation of functionality within the transaction service?
No the transaction service is not affected by this beyond the fact that transactions like the one above that rely on divulgence eventually cannot appear there anymore once we turn the deprecation into an error.
Thanks for the clarification. Can you assist me in understanding what is going on with the following example. Similar to yours, except I added choice observers and flexible controllers.
module Main2 where
import Daml.Script
template T
with
p : Party
where
signatory p
template Divulger
with
sig : Party
obs : Party
where
signatory sig
observer obs
nonconsuming choice Divulger_Fetch : T
with
cid : ContractId T
ctrl : Party
choiceObs : Party
observer choiceObs
controller ctrl
do
fetch cid
test_fetch = script do
p1 <- allocateParty "p1"
p2 <- allocateParty "p2"
p3 <- allocateParty "p3"
tCid <- submit p1 $ createCmd (T p1)
divulgerCid <- submit p1 $ createCmd (Divulger p1 p2)
submitMustFail p2 $ exerciseCmd divulgerCid (Divulger_Fetch tCid p2 p3)
submit p1 $ exerciseCmd divulgerCid (Divulger_Fetch tCid p1 p3) -- If I change p3 to p2 here, then the line below succeeds
submit p2 $ exerciseCmd divulgerCid (Divulger_Fetch tCid p2 p3) -- This fails, but was thinking this should work as the contract was divulged to p2 in previous line?
pure ()
My understanding was that the choice consequences will be divulged to the union of: signatories, observers and choice observers. But this seems to not be the case in the above example. I must be missing something here.
Observers only see consuming not non-consuming choices. There is also a list of parties missing from your list: the controllers of the choice (which can also be observers in which case they see a non-consuming choice).
In your example, p1 is the signatory, p2 is an observer but not a controller and it’s a non-consuming choice so they don’t see the consequences and p3 is a choice observer so the see the choice.
Thanks for that. More learning for me to do!