咨询Initiator flow中Responder flow的调用时机及执行逻辑
Great questions—let's break this down clearly since Initiator/Responder flows are core to how peer-to-peer transaction workflows operate (I’m assuming we’re talking about Corda here, since this is the most common context for these flow types).
When is the Responder Flow Triggered in the Initiator Flow?
The Responder flow is automatically triggered by the receiving node’s flow framework when an Initiator flow initiates a communication session and sends a message to it. Here’s the play-by-play:
- First, the Initiator uses
initiateFlow(targetParty)to establish a direct peer-to-peer session with the responder’s node. - When the Initiator sends the first message (like a transaction proposal, or any data payload) over this session, the responder’s node scans for a flow class annotated with
@InitiatedBy(InitiatorFlow::class)—this annotation links the Responder flow to its corresponding Initiator. - The node then spins up an instance of that Responder flow to handle the incoming session and message. No manual activation is needed; it’s all handled by the underlying flow runtime.
Responder Flow Execution Timing & How It Checks/Signs Transactions
Let’s split this into two parts for clarity:
Execution Timing
The Responder flow is passively activated—it only runs when the paired Initiator flow reaches out and starts the conversation. Its lifecycle is tied directly to the session:
- It starts the moment the first message from the Initiator is received.
- It runs until the session concludes (either the transaction is fully signed and committed, the flow completes its logic, or the session is terminated prematurely).
How It Checks & Signs Transactions
A typical Responder flow follows these key steps to validate and sign a transaction:
- Receive the transaction proposal: It first accepts the partially signed transaction (or transaction components) sent by the Initiator, often using
session.receive<T>().unwrap { ... }to safely deserialize the data. - Validate the transaction:
- Participation check: Ensures the responder’s node is actually a participant in the transaction (e.g., listed in the state’s
participantsfield) and has the right to sign. - Business rule validation: Verifies the transaction adheres to custom business logic (e.g., ensuring an asset transfer amount is positive, or that the sender owns the asset being transferred).
- Structural validation: Checks that the transaction is formatted correctly—valid inputs/outputs, valid commands, and that any existing signatures (from the Initiator) are cryptographically sound.
- Participation check: Ensures the responder’s node is actually a participant in the transaction (e.g., listed in the state’s
- Sign the transaction: If all checks pass, the Responder uses its node’s signing key to sign the transaction via
serviceHub.signInitialTransaction(...)or similar methods. - Send the signature back: It transmits the signed transaction (or just the signature) to the Initiator to continue the workflow.
- Optional: Wait for finalization: Many Responders will run
ReceiveFinalityFlowto wait for the fully signed transaction to be committed to the ledger, ensuring consistency across all participating nodes.
Here’s a simplified code snippet to illustrate this flow:
@InitiatedBy(InitiatorFlow::class) class ResponderFlow(private val session: FlowSession) : FlowLogic<SignedTransaction>() { override fun call(): SignedTransaction { // Receive and unwrap the partially signed transaction from Initiator val partiallySignedTx = session.receive<SignedTransaction>().unwrap { it } // Validate we're a participant in the transaction require(partiallySignedTx.tx.outputsOfType<MyCustomState>().any { it.participants.contains(ourIdentity) }) { "Our node isn't a participant in this transaction—cannot sign." } // Add custom business validation here (e.g., check state values) // Sign the transaction with our node's key val ourSignature = serviceHub.signInitialTransaction(partiallySignedTx) // Send our signature back to the Initiator session.send(ourSignature) // Wait for the final signed transaction to be committed to the ledger return subFlow(ReceiveFinalityFlow(session, partiallySignedTx.id)) } }
内容的提问来源于stack exchange,提问作者viswa




