Unable to create contract using parties of another domain

I have a multi-domain setup. I have 2 participant nodes and 2 domains. The participant nodes are connected as per below.

if (participant1.domains.list_registered().isEmpty) {
    // make initial connections to domain
    participant1.domains.connect("domain1", "http://domain1:3000")
    participant1.domains.connect("domain2", "http://domain2:3010")
}
if (participant2.domains.list_registered().isEmpty) {
    // make initial connections to domain
    participant2.domains.connect("domain1", "http://domain1:3000")
    participant2.domains.connect("domain2", "http://domain2:3010")
}

I noticed that parties allocated on each participant node is made available on another participant node with a flag isLocal False.

When I use these parties (whose isLocal is False) to create a contract, I get the below exception.

Caused by: io.grpc.StatusRuntimeException: NOT_FOUND: NO_DOMAIN_ON_WHICH_ALL_SUBMITTERS_CAN_SUBMIT(11,9ec5980b): This participant can not submit as the given submitter on any connected domain
at io.grpc.Status.asRuntimeException(Status.java:535)
at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:534)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:562)
at io.grpc.internal.ClientCallImpl.access$300(ClientCallImpl.java:70)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:743)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:722)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)

E.g. If Parties A, B are allocated on Participant node 1 and Parties C & D are allocated on Participant Node 2, can I use the party C (available as isLocal False) to create a contract on Participant node 1?

I am a beginner to DAML and Canton, appreciate your help to understand this issue.

2 Likes

Are you creating your contract from a Daml script ? If yes, how do you launch your script ?
Have you specify the -participant-config as below ?

daml script --dar .daml/dist/DAR-FILE-1.0.0.dar \
    --script-name Scripts.Setup:setup \
    --participant-config participant-config.json

I am not using DAML script, but using Java bindings to create our contract. Below is our code snippet.

The party passed to the function submitAndWaitForTransaction is the party allocated on other domain.

DepositRequestProposal depositRequestProposal = new DepositRequestProposal(
            toAccount, 
            requestDepositDto.getAmount(),
            requestDepositDto.getCurrency(), 
            ProposalStatus.INITIATED
        );
        var createDepositCommand = depositRequestProposal.create().toProtoCommand();
        return damlClientWrapper.getCommandClient().submitAndWaitForTransaction(
            Constants.CREATE_DEPOSIT_WORKFLOW,
            Constants.APP_ID,
            UUID.randomUUID().toString(),
            toAccount.accountOwner.bank,
           Collections.singletonList(com.daml.ledger.javaapi.data.Command.fromProtoCommand(createDepositCommand)))
            .blockingGet();

You can only submit a command for a party on the participant that party is hosted on. Judging from the error it sounds like bank might be hosted on participant1 but your Java code is talking to participant2 or the other way around.