allocatePartyWithHintOn and listKnownPartiesOn behaving unexpectedly

Hey all. I was trying to use Daml script to simulate a multi-party scenario but I am completely unable to make allocatePartyWithHintOn allocate parties on specific participants.

In my Canton setup I have two participants:

  • participant1, which connects to domain1
  • participant2, which connects to domain2

I exported this to participants.json (with participant1 as the default participant) and I pass that to daml script.

In the script I have the following code:

bob     <- allocatePartyWithHintOn "Bob"     (PartyIdHint "Bob")     (ParticipantName "participant1")
bobette <- allocatePartyWithHintOn "Bobette" (PartyIdHint "Bobette") (ParticipantName "participant2")

The issue I have is that it seems to be ignoring the participant name. Instead it always seems to do everything on the default participant.

In Canton, when I enter participant1.parties.list() I see both Bob and Bobette (and participant1). If I enter participant2.parties.list() I see neither (I only see participant2).

Interestingly, when i try to use listKnownPartiesOn in the Daml script then I see Bob and Bobette and participant1 regardless of what I enter for participant name.

Finally I want to point out that allocatePartyWithHintOn and listKnownPartiesOn behave this way even when I enter a participant name that doesn’t exist at all.

So what gives? Why might this not be working as I would expect it to?

Can you share your participants.json?

Sure thing. I added some other files also in case they’re useful.

participants.json:

{
  "default_participant" : {
    "host" : "127.0.0.1",
    "port" : 5021
  },
  "participants" : {
    "participant1::12203fe150cc7164836135fa48031cca0ce396e8a2fbc6b7eaed564bd30cfeb13a62" : {
      "host" : "127.0.0.1",
      "port" : 5011
    },
    "participant2::12200c67a3d938e73431c240e07490536eefad6610b2d6cd14fb7b4b08cdaa37bf4f" : {
      "host" : "127.0.0.1",
      "port" : 5021
    }
  },
  "party_participants" : {
    "participant1::12203fe150cc7164836135fa48031cca0ce396e8a2fbc6b7eaed564bd30cfeb13a62" : "participant1::12203fe150cc7164836135fa48031cca0ce396e8a2fbc6b7eaed564bd30cfeb13a62",
    "participant2::12200c67a3d938e73431c240e07490536eefad6610b2d6cd14fb7b4b08cdaa37bf4f" : "participant2::12200c67a3d938e73431c240e07490536eefad6610b2d6cd14fb7b4b08cdaa37bf4f"
  }
}

canton.conf:

canton {
  participants {
    participant1 {
      storage.type = memory
      admin-api.port = 5012
      ledger-api.port = 5011
    }
    participant2 {
      storage.type = memory
      admin-api.port = 5022
      ledger-api.port = 5021
    }
  }
  domains {
    domain1 {
      storage.type = memory
      public-api.port = 5018
      admin-api.port = 5019
    }
    domain2 {
      storage.type = memory
      public-api.port = 5028
      admin-api.port = 5029
    }
  }
  // enable ledger_api commands for our getting started guide
  features.enable-testing-commands = yes
}

setup.canton:

nodes.local start

println("participant1 connects only to domain1")
participant1.domains.connect_local(domain1)

println("participant2 connects only to domain2")
participant2.domains.connect_local(domain2)

participants.all.dars.upload("generated/script.dar")

val participantConfigFile = "./generated/participants.json"
println(s"📝 ${participantConfigFile}")
utils.generate_daml_script_participants_conf(Some(participantConfigFile), Some(participant2))

Script.daml:

module Script where

import Daml.Script

import DA.Foldable (forA_)

go : Script ()
go = do
  bob     <- allocatePartyWithHintOn "Bob"     (PartyIdHint "Bob")     (ParticipantName "participant1")
  bobette <- allocatePartyWithHintOn "Bobette" (PartyIdHint "Bobette") (ParticipantName "participant2")

  forA_ ["participant1", "participant2", "doesnotexist"] $ \name -> do
    debugRaw $ "Parties on " <> name <> ":"
    listKnownPartiesOn (ParticipantName name) >>= debug

(Actually I just noticed that this has one change compared to my post. Here participant2 is the default participant, and so that’s where the parties show up.)

The participant name you use in Daml must match the key of the corresponding JSON object. You have particpant1 in your Daml code but then participant1::122… in your JSON file. If you get the two in sync, it should work properly.

Note that default_participant is optional. If you remove that, you should get an error if there is a mismatch rather than a fallback to default_participant.

@cocreature Thanks. That makes perfect sense. It’s really confusing, though, that it silently falls back to the default participant.