Display the state information to a list of participants dynamically

I have tweeked the Yo- CordApp to send to a list of participants instead of single participant in the target. I would like to send the YO to more than one Party, moreover I just want to display the state information to the parties which does not require the signatures of all parties. But I am stuck with the below error. Please help.

FlowLogicRef cannot be constructed for FlowLogic of type net.corda.yo.YoFlow as could not find matching constructor for: {target=null}

The link to my code: GitHub - ayinot/CordaProjects: Yo-CordaApp.

The error suggests that the YoFlow constructor is being called incorrectly due to a mismatch between the arguments provided and the expected parameters in the flow’s definition. When modifying the YoFlow to target multiple participants, it’s essential to ensure that the flow’s structure and parameters align with the expected usage.

Here’s how to fix this issue step-by-step:


1. Update Your Flow Definition

Modify your YoFlow class to accept a list of targets instead of a single target. The constructor should reflect this change.

Example:

@InitiatingFlow
@StartableByRPC
class YoFlow(private val targets: List<Party>, private val message: String) : FlowLogic<Unit>() {

    @Suspendable
    override fun call() {
        // Get the notary
        val notary = serviceHub.networkMapCache.notaryIdentities.first()

        // Create the YoState
        val yoState = YoState(message, ourIdentity, targets)

        // Build the transaction
        val txBuilder = TransactionBuilder(notary)
            .addOutputState(yoState, YoContract.ID)
            .addCommand(YoContract.Commands.Send(), ourIdentity.owningKey)

        // Verify the transaction
        txBuilder.verify(serviceHub)

        // Sign the transaction
        val signedTx = serviceHub.signInitialTransaction(txBuilder)

        // Send the transaction to all targets
        for (target in targets) {
            subFlow(FinalityFlow(signedTx, listOf(initiateFlow(target))))
        }
    }
}

2. Modify Your State

Ensure the YoState supports a list of participants. Update its participants property to reflect this:

Example:

data class YoState(
    val message: String,
    val sender: Party,
    val receivers: List<Party>,
    override val participants: List<Party> = receivers
) : ContractState

3. Update the Flow Caller

When calling the YoFlow, ensure you provide a list of parties instead of a single party. For example:

val targetParties = listOf(partyA, partyB, partyC)
val message = "Hello, Corda!"
subFlow(YoFlow(targetParties, message))

4. Handle the Error

The error occurs because your constructor does not match the arguments passed in the FlowLogicRef creation. Verify that the flow parameters in your RPC call or initiator match the updated constructor.

Before:

subFlow(YoFlow(partyB, "Hello!"))

After (with a list):

val targetParties = listOf(partyB, partyC)
subFlow(YoFlow(targetParties, "Hello!"))

5. Troubleshoot the Error

If the error persists:

  1. Check Your RPC Start Flow Call: Ensure that the RPC client starts the flow with a list of participants.Example:
val targets = listOf("O=PartyA,L=London,C=GB", "O=PartyB,L=New York,C=US")
proxy.startFlow(::YoFlow, targets, "Hello, everyone!")
  1. Clear Old Artifacts:
  • Stop the node and clear any old artifacts in the build or cordapps directories.
  • Rebuild the CorDapp using:
./gradlew clean deployNodes
  • Restart the nodes.
  1. Check Flow Registration: Ensure the YoFlow is properly annotated with @StartableByRPC or @StartableByService if it’s being called via RPC or other services.

6. Test the Flow

  • Verify that the flow sends the state to multiple parties without requiring all parties’ signatures (as only the sender signs it in this example).
  • Check that the participants list in the state reflects all intended recipients.

By following these steps, your YoFlow should handle multiple participants seamlessly. Let me know if you encounter additional issues!