Deprecation of using Divulged Contracts

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?

2 Likes

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:

  1. There is a contract cid where p1 is the only stakeholder.
  2. There is a contract fetcher which is signed by p1 and has p2 as an observer. That contract allows p2 to fetch a contract with p1’s authorization.
  3. However, if you try that, you’ll get an error saying that the contract is not visible to the submitter.
  4. Now, we create a divulger contract which is the same as fetcher but with the roles switched.
  5. p1 can execute the Fetch here since they are a stakeholder on cid. Because p2 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.
  6. 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.

2 Likes

Thanks for that example. I think I’m understanding this now. Is there any deprecation of functionality within the transaction service?

1 Like

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.

2 Likes

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.

1 Like

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.

2 Likes

Thanks for that. More learning for me to do!