Managing contention by catching `CONTRACT_NOT_FOUND` errors
Consider the following model, where I can have multiple outstanding offers for an asset to be transferred.
template ProposeAsset
with
assetId : ContractId Asset
owner : Party
recipient : Party
where
signatory owner
observer recipient
choice Accept : ContractId AcceptAsset
controller recipient
do create AcceptAsset with assetId, currentOwner = owner, newOwner = recipient
template AcceptAsset
with
assetId : ContractId Asset
currentOwner : Party
newOwner : Party
where
signatory newOwner
observer currentOwner
choice Finalize : ContractId Asset
controller currentOwner
do
archive assetId
create Asset with owner = newOwner
template Asset
with
owner : Party
where
signatory owner
nonconsuming choice Propose : ContractId ProposeAsset
with
recipient : Party
controller owner
do create ProposeAsset with
assetId = self
owner = owner
recipient = recipient
This model is prone to contention, as shown in the following test script, which “successfully fails”:
testAssetCannotBeGivenTwice : Script ()
testAssetCannotBeGivenTwice = script do
-- user_setup_begin
alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
bob <- allocatePartyWithHint "Bob" (PartyIdHint "Bob")
charlie <- allocatePartyWithHint "Charlie" (PartyIdHint "Charlie")
aliceId <- validateUserId "alice"
bobId <- validateUserId "bob"
charlieId <- validateUserId "charlie"
createUser (User aliceId (Some alice)) [CanActAs alice]
createUser (User bobId (Some bob)) [CanActAs bob]
createUser (User charlieId (Some charlie)) [CanActAs charlie]
-- user_setup_end
asset <- submit alice do
createCmd Asset with
owner = alice
offerToBob <- submit alice do
exerciseCmd asset Propose with recipient = bob
bobAccepts <- submit bob do exerciseCmd offerToBob Accept
offerToCharlie <- submit alice do
exerciseCmd asset Propose with recipient = charlie
charlieAccepts <- submit charlie do exerciseCmd offerToCharlie Accept
submit alice do exerciseCmd bobAccepts Finalize
submitMustFail alice do exerciseCmd charlieAccepts Finalize
Ideally, I would like to handle contention-related issues explicitly in my model.
For this reason, I would like to catch CONTRACT_NOT_FOUND errors and return an Optional ContractId Asset. Is that possible?
You cannot catch contention errors within Daml. Daml exceptions are resolved during submission. However, contention errors usually only fail during validation. At that point, interpretation is already fixed and the transaction can only get accepted or rejected. To support handling that it would instead need to get reinterpreted in some form.