Corda returning Multiple transactions in a single flow call ()

微笑、不失礼 提交于 2019-12-11 16:30:56

问题


I have the scenario where One party needs to read a list of states ( DEAL STATE for ex.), Then iterate through the list to find out the matching records. If it is matching, we need to create new output state by combining the matched fields.

So once the matching is performed within the loop, we can get the list of input and output states.

But I am confused on collecting the signature from other parties since the counterparties will be different for each of the record. Also, how will I call the finality flow for multiple transactions within single flow call method?

@joel, Another problem - Suppose outputstate1 particicpants are say A, B, C, and outputstate2 paticipants are B, C ,D ,ie B & C are involved in 2 transactions. So within matching states loop, when we make flowsessions map, it will have the signers are A, B, C, D. But when we call CollectSignaturesFlow, we need to pass each of the partialsigned trxn and sessions. So how to pass the session corresponding to a trxn ?


回答1:


Here's an example of how we could collect the signatures for each state:

val flowSessionMap = mutableMapOf<Party, FlowSession>()

val fullySignedTransactions = matchingStates.forEach { matchingState ->
    val requiredSigners: List<Party> = TODO("Derive this from the matching state somehow.")
    val signedTransaction: SignedTransaction = TODO("Build transaction.")

    val sessions = requiredSigners.map { signer ->
        flowSessionMap.getOrPut(signer) {
            initiateFlow(signer)
        }
    }

    val fullySignedTransaction = subFlow(CollectSignaturesInitiatingFlow(
        signedTransaction, sessions)
    )
}

Where CollectSignaturesInitiatingFlow is defined as follows:

@InitiatingFlow
class CollectSignaturesInitiatingFlow(val signedTransaction: SignedTransaction, val sessions: List<FlowSession>): FlowLogic<SignedTransaction>() {
    override fun call(): SignedTransaction {
        return subFlow(CollectSignaturesFlow(signedTransaction, sessions))
    }
}

And the responder for CollectSignaturesInitiatingFlow is defined as follows:

@InitiatedBy(CollectSignaturesInitiatingFlow::class)
class CollectSignaturesInitiatingFlowResponder(val otherPartyFlow: FlowSession) : FlowLogic<SignedTransaction>() {
    @Suspendable
    override fun call(): SignedTransaction {
        val signTransactionFlow = object : SignTransactionFlow(otherPartyFlow) {
            override fun checkTransaction(stx: SignedTransaction) {
                TODO("Check the transaction here.")
            }
        }

        return subFlow(signTransactionFlow)
    }
}

Note that:

  • We're being careful to only create one session per counterparty. As of Corda 3, an error will be thrown if a flow creates multiple sessions per counterparty
  • We're wrapping the call to CollectSignaturesFlow in CollectSignaturesInitiatingFlow. Why? In Corda, there are two types of flow: Initiating and inlined. Each Initiating flow instance has a unique ID, while each inlined flow inherits the ID of the flow that called it as a subflow. As of Corda 3, an exception is thrown if a responder is invoked twice for the same flow ID. By wrapping CollectSignaturesFlow (an inlined flow) inside CollectSignaturesInitiatingFlow (an Initiating flow), we create a new flow ID for each attempt to gather signatures, and no exception is thrown

Once you have the fully-signed transactions, you can call FinalityFlow in a loop:

for (transaction in fullySignedTransactions) {
    subFlow(FinalityFlow(transaction))
}


来源:https://stackoverflow.com/questions/50797667/corda-returning-multiple-transactions-in-a-single-flow-call

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!