I am trying to create a simple example to illustrate the guidance in the old topic, Cyclic dependencies.
What if I start with a PingPong module, like this:
PingPong.daml
module PingPong where
template Ping with
party : Party
where
signatory party
choice RespondWithPong : ContractId Pong
controller party
do create Pong with ..
template Pong
with party : Party
where
signatory party
choice RespondWithPing : ContractId Ping
controller party
do create Ping with ..
Let’s pretend the PingPong module is getting too big. We would like to break it into two pieces – a module for Pings and a module for Pongs.
Naively copy-and-pasting the two templates into new modules results in the Cyclic module dependency between Pings, Pongs error.
Pings.daml
module Pings where
import Pongs
template Ping with
party : Party
where
signatory party
choice RespondWithPong : ContractId Pong
controller party
do create Pong with ..
Pongs.daml
module Pongs where
import Pings
template Pong
with party : Party
where
signatory party
choice RespondWithPing : ContractId Ping
controller party
do create Ping with ..
For this contrived example, what would the Daml look like when applying @bernhard’s suggestion:
I believe the example you created falls into the description the the first paragraph in @bernhard’s reply. Since the templates are too simple to be broken apart into multiple ones, I see no option here to resolve the dependency other than moving the two templates into the same module (as they were originally).
The example is definitely simple and contrived. I was thinking about it over the weekend and the best I could come up with is this:
Ping and Pong templates no longer generate the responses, since they cannot know about each other. (These become the “upstream”)
Introduce new Pinging and Ponging templates to generate the responses. (These are the “downstream”).
I’d welcome a better example!
Ping.daml
module Ping where
template Ping with
party : Party
where
signatory party
Pong.daml
module Pong where
template Pong with
party : Party
where
signatory party
Pinging.daml
module Pinging where
import Ping
import Pong
template Pinging
with party : Party
where
signatory party
choice Create : ContractId Ping
controller party
do create Ping with ..
choice Respond : ContractId Ping
with pong : ContractId Pong
controller party
do
archive pong
create Ping with..
Ponging.daml
module Ponging where
import Ping
import Pong
template Ponging
with party : Party
where
signatory party
choice Create : ContractId Pong
controller party
do create Pong with..
choice Respond : ContractId Pong
with ping : ContractId Ping
controller party
do
archive ping
create Pong with..
Main.daml
module Main where
import Daml.Script
import Pinging
import Ponging
demo = script do
party <- allocateParty "party"
ping <- submit party $ createAndExerciseCmd (Pinging party) Pinging.Create
pong <- submit party $ createAndExerciseCmd (Ponging party) Ponging.Respond with ..
ping <- submit party $ createAndExerciseCmd (Pinging party) Pinging.Respond with ..
pure ()