Andranik
Andranik

Reputation: 2849

Corda 4.1 Unable to determine which flow to use

After updating to Corda 4.1 from 3.3, when I run the node with deployNodes I get the following error:

[main] internal.NodeStartupLogging.invoke - Exception during node startup: Unable to determine which flow to use when responding to: com.example.CreateDealFlow.Sender. [com.example.CreateDealFlow.Receiver, com.example.CreateDealFlow.Receiver] are all registered with equal weight. [errorCode=mnl04m, moreInformationAt=https://errors.corda.net/OS/4.1/mnl04m]

there is no any information when I go through URL in error.

My flow looks something like this(I have simplified the code and removed custom logics, just what matters for this case is there)

    object CreateDealFlow {

    @InitiatingFlow
    @StartableByService
    class Sender(private val dataHolder: DealDataHolder) : FlowLogic<SignedTransaction>() {

        @Suspendable
        override fun call(): SignedTransaction {
            val sender = PartyAndCompany(dataHolder.senderUUID, ourIdentity)
            val receiver = PartyAndCompany(dataHolder.receiverUUID, getPartyFromX500String(dataHolder.receiverX500String))

            val txBuilder = buildTransaction(sender = sender, receiver = receiver)
            txBuilder.verify(serviceHub)

            val partiallySignedTransaction = serviceHub.signInitialTransaction(txBuilder)
            val parties = partiallySignedTransaction.tx.outputStates.first().participants
            val (fullySignedTx, flowSessions) = collectSignaturesFromReceivers(partiallySignedTransaction, parties)

            return subFlow(FinalityFlow(fullySignedTx, flowSessions, FinalityFlow.tracker()))
        }

        @Suspendable
        fun buildTransaction(sender: PartyAndCompany, receiver: PartyAndCompany): TransactionBuilder {

        }
    }

    @InitiatedBy(CreateDealFlow.Sender::class)
    class Receiver(val otherPartyFlow: FlowSession) : FlowLogic<SignedTransaction>() {


        @Suspendable
        override fun call(): SignedTransaction {
            val signTransactionFlow = object : SignTransactionFlow(otherPartyFlow) {

                override fun checkTransaction(stx: SignedTransaction) = requireThat {

                }

            }

            val txWeJustSigned = subFlow(signTransactionFlow)
            return subFlow(ReceiveFinalityFlow(otherPartyFlow, expectedTxId = txWeJustSigned.id))
        }
    }
}

Upvotes: 0

Views: 234

Answers (1)

Dan Newton
Dan Newton

Reputation: 920

Resolved by Andranik himself 🙂

The issue was due to having 3 CorDapps (workflows, contracts, workflows-2).

workflows-2 depends on workflows. To do so it was using a compile dependency. When delpoyNodes was run this was building in the workflows code into workflows-2 (a.k.a fat jarring). This then failed at runtime since there were now two CorDapps that contained a flow found in workflows.

To resolve this, cordaCompile was used. This included the workflows module as a compile time dependency but does not build it into the jar. When the node is ran, the flow is loaded from the workflows CorDapp and loaded onto the classpath where workflows-2 can now also access it.

Upvotes: 3

Related Questions