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
p1is the only stakeholder.
- There is a contract
fetcherwhich is signed by p1 and has p2 as an observer. That contract allows
p2to fetch a contract with
- However, if you try that, you’ll get an error saying that the contract is not visible to the submitter.
- Now, we create a
divulgercontract which is the same as
fetcherbut with the roles switched.
p1can execute the
Fetchhere since they are a stakeholder on
p2is 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
p2has 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!