Divulgence only on consuming choices
Why does only the default “consuming” choice below cause divulgence?
module Main where
import Daml.Script
template Secret
with
p : Party
where
signatory p
template SecretFetcher
with
p : Party
obs : [Party]
where
signatory p
observer obs
choice PublicFetch : Secret
with s : ContractId Secret
controller p
do fetch s
nonconsuming choice NonPublicFetch : Secret
with s : ContractId Secret
controller p
do fetch s
preconsuming choice PreconsumingFetch : Secret
with s : ContractId Secret
controller p
do fetch s
postconsuming choice PostconsumingFetch : Secret
with s : ContractId Secret
controller p
do fetch s
nonconsuming choice CustomPreconsumingFetch : Secret
with s : ContractId Secret
controller p
do
archive self
fetch s
nonconsuming choice CustomPostconsumingFetch : Secret
with s : ContractId Secret
controller p
do
x <- fetch s
archive self
return x
template Fetcher
with
stakeholder : Party
fetcher : Party
where
signatory stakeholder
observer fetcher
nonconsuming choice FetchSecret : Secret
with
cid : ContractId Secret
controller fetcher
do fetch cid
test : Choice SecretFetcher c Secret => Party -> Text -> Bool -> (ContractId Secret -> c) -> Script ()
test p observerName divulged f = do
o <- allocateParty observerName
s <- submit p do createCmd Secret with p
sf <- submit p do createCmd SecretFetcher with p; obs = [o]
submit p do exerciseCmd sf (f s)
f <- submit p do createCmd Fetcher with stakeholder = p; fetcher = o
if divulged then do
submit o do exerciseCmd f $ FetchSecret s
pure ()
else
submitMustFail o do exerciseCmd f $ FetchSecret s
privacyTest : Script ()
privacyTest = do
p <- allocateParty "p"
test p "publicFetcher" True PublicFetch
test p "nonconsumingPublic" False NonPublicFetch
test p "preconsumingFetcher" False PreconsumingFetch
test p "postconsumingFetcher" False PostconsumingFetch
test p "customPreFetcher" False CustomPreconsumingFetch
test p "customPostFetcher" False CustomPostconsumingFetch
It’s described in the privacy section of the ledger model.
a party p is an informee of an action A if one of the following holds:
- A is a consuming Exercise on a contract c, and p is a stakeholder of c or an actor on A.
- A is a non-consuming Exercise on a contract c, and p is a signatory of c or an actor on A.
- A is an Exercise action and p is a choice observer on A.
The idea here is that stakeholders are entitled to see contract state changes, i.e., create and archive. The slightly unfortunate thing here is that there is no separate archive primitive in Daml so “see contract archive” really means “see consuming exercise”.
The preconsuming keyword allows you to sidestep that by desugaring the choice to a non-consuming choice that calls archive at the beginning so observers really only see the exercise of the archive choice.
The ledger model docs also have the workaround for the case where you actually want to share the full choice: Add the party as a choice observer.
Maybe the question should have been - why does only the default choice cause divulgence and the others do not? Specifically, why does post-consuming not cause divulgence? Is this because all the others are effective non-consuming (preconsuming and postconsuming just being the same as the CustomXXX variants)?
Yes, post-consuming and pre-consuming are just syntactic sugar for non-consuming + a call to the autogenerated archive choice at the beginning/end.
@cocreature I think the part that you quoted only defines the informee’s if they are acting on the ledger not passively observing, but that did lead me to the part that clarifies it which is right above
As a design choice, Daml Ledgers show to contract observers only the state changing actions on the contract. More precisely, Fetch and non-consuming Exercise actions are not shown to contract observers - except when they are also actors or choice observers of these actions
The contract state is defined
The contract state is changed by creating the contract and by exercising it consumingly.
More precisely, Fetch and non-consuming Exercise actions are not shown to contract observers…
But I thought a fetch causes divulgence to contract observers? Isn’t it only non-consuming exercises that are not shown to contract observers?
@Mr_Mannoroth In this context is is the fetch of the contract in a different Update that is not disclosed to an observer.
