# CONTRACT\_NOT\_FOUND with Daml Script across multiple nodes

**URL:** <https://forum.canton.network/t/contract-not-found-with-daml-script-across-multiple-nodes/7013>\
**Category:** App Development\
**Tags:** daml\
**Created:** [January 5, 2024, 4:23pm UTC](https://forum.canton.network/t/contract-not-found-with-daml-script-across-multiple-nodes/7013 "2024-01-05T16:23:39Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![WallaceKelly](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/wallacekelly/32/5046_2.png) [@WallaceKelly](https://forum.canton.network/u/WallaceKelly)\
**Post date:** [January 5, 2024, 4:23pm UTC](https://forum.canton.network/t/contract-not-found-with-daml-script-across-multiple-nodes/7013/1 "2024-01-05T16:23:39Z")

</div>

# Background

I am running a single Daml script which submits commands against two different participant nodes. I am using open source Canton 2.7.6 and three Docker containers (`participant1`, `participant2`, and `mydomain`.)

 ![image](https://canada1.discourse-cdn.com/flex028/uploads/daml/original/2X/6/691489778291c32453fb95802c294590c4142c4a.png)

I am doing this with the `party_participants` field of a `participants.config`, using `daml script --participant-config`.

The setup works great, except…

# Problem

I am getting a `CONTRACT_NOT_FOUND` when bob tries to submit his proposal:

```haskell
  debug "Alice creating a bid request..."
  bidRequest <- submit alice do createCmd BidRequest with owner = alice, painter = bob

  debug "Bob submitting a proposal..."
  bid <- submit bob do exerciseCmd bidRequest Propose with amount = 1000.0

  debug "Alice accepting the proposal..."
  contract <- submit alice do exerciseCmd bid Accept

```

I _believe_ it is a race condition. Inserting `sleep (seconds 5)` between the submits avoids the `CONTRACT_NOT_FOUND` exceptions.

I _expected_ that by the time participant1’s Ledger API returns a contract id, that I could submit the contract id against participant2’s Ledger API.

# Questions

- What is causing this race condition?
- What can make this script work today? For example, is there a Canton config setting that would remove this race condition?
- Is this something that we should “fix” to better support Daml scripting across multiple nodes?

---

<div class="post-metadata">

**Author:** ![WallaceKelly](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/wallacekelly/32/5046_2.png) [@WallaceKelly](https://forum.canton.network/u/WallaceKelly)\
**Post date:** [January 5, 2024, 7:51pm UTC](https://forum.canton.network/t/contract-not-found-with-daml-script-across-multiple-nodes/7013/2 "2024-01-05T19:51:50Z")

</div>

I just found [this post](https://discuss.daml.com/t/init-script-on-a-canton-setup/3009/6) by @cocreature.

> Note that there is no automatic synchronisation between participants however. So if you submit a transaction on one participant it will not block until that transaction is visible on the other participant. You can do things like poll for a contract id created in that transaction to appear on the other participant via `queryContractId` to synchronize manually.

```haskell
waitForCid : Template t => Party -> ContractId t -> Script ()
waitForCid p cid = do
  r <- queryContractId p cid
  case r of
    None -> do
      sleep (seconds 1)
      waitForCid p cid
    Some _ -> pure ()

```

> I opened [Easier multi-participant synchronization in Daml Script · Issue #10618 · digital-asset/daml · GitHub](https://github.com/digital-asset/daml/issues/10618) to improve the UX for synchronization in Daml Script.

---

<div class="post-metadata">

**Author:** ![cocreature](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/cocreature/32/36_2.png) [@cocreature](https://forum.canton.network/u/cocreature)\
**Post date:** [January 8, 2024, 8:08am UTC](https://forum.canton.network/t/contract-not-found-with-daml-script-across-multiple-nodes/7013/3 "2024-01-08T08:08:15Z")

</div>

> What is causing this race condition?

In your example, you submit against participant1. The `submit` call returns once the transaction has been committed and participant1 has processed it. However, participant1 and participant2 are not synchronized so participant2 might not have processed the transaction fully yet.

> What can make this script work today? For example, is there a Canton config setting that would remove this race condition?

I think `waitForCid` is your best option for making this work in Daml Script.

> Is this something that we should “fix” to better support Daml scripting across multiple nodes?

I’d be slightly cautious here: This asynchronous behavior is a fundamental thing you need to pay attention to in distributed setups. What I’ve found to work quite well is that once you’re actually working with multiple participants, drop Daml script (which is great for testing but not really suited for orchestrating complex distributed deployments) and instead do initialization from your app backends where each backend only talks to one participant. That way it becomes very explicit and you can add retries as needed for synchronization.

---

<div class="post-metadata">

**Author:** ![WallaceKelly](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/wallacekelly/32/5046_2.png) [@WallaceKelly](https://forum.canton.network/u/WallaceKelly)\
**Post date:** [January 8, 2024, 2:04pm UTC](https://forum.canton.network/t/contract-not-found-with-daml-script-across-multiple-nodes/7013/4 "2024-01-08T14:04:03Z")

</div>

> [@cocreature](#):
>
> However, participant1 and participant2 are not synchronized so participant2 might not have processed the transaction fully yet.

Would the situation be any different if the two parties were both _signatories_?

---

<div class="post-metadata">

**Author:** ![cocreature](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/cocreature/32/36_2.png) [@cocreature](https://forum.canton.network/u/cocreature)\
**Post date:** [January 8, 2024, 2:30pm UTC](https://forum.canton.network/t/contract-not-found-with-daml-script-across-multiple-nodes/7013/5 "2024-01-08T14:30:16Z")

</div>

> [@WallaceKelly](#):
>
> Would the situation be any different if the two parties were both _signatories_?

No, both participants have to confirm the transaction in that case for it to be committed but that does still not ensure that the participant has ingested the transaction in the right store after the submission on the other participant completes.

---

<div class="post-metadata">

**Author:** ![WallaceKelly](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/wallacekelly/32/5046_2.png) [@WallaceKelly](https://forum.canton.network/u/WallaceKelly)\
**Post date:** [January 16, 2024, 8:59pm UTC](https://forum.canton.network/t/contract-not-found-with-daml-script-across-multiple-nodes/7013/6 "2024-01-16T20:59:47Z")

</div>

Thanks, @cocreature, for the help!

I have distilled what I have learned in an article [Multi-participant Daml Scripts](https://discuss.daml.com/t/multi-participant-daml-scripts/7039).
