问题
i*m using Corda 4.0 RC1 and have a clone of the cash-issuer repository; there i have a Corda-ResponderFlow which should do a business test; currently it throws an exception; the flow is programmed in this way
class ReceiveBankAccount(val otherSession: FlowSession) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
logger.info("Starting ReceiveBankAccount flow...")
val signedTransactionFlow = object : SignTransactionFlow(otherSession) {
@Suspendable
override fun checkTransaction(stx: SignedTransaction) = requireThat {
val bankAccountState = stx.tx.outputsOfType<BankAccountState>().single()
val result = getBankAccountStateByAccountNumber(bankAccountState.accountNumber, serviceHub)
if (result != null) {
val linearId = result.state.data.linearId
throw IllegalArgumentException("Bank account $bankAccountState already exists with linearId ($linearId).")
}
}
}
subFlow(signedTransactionFlow)
if (!serviceHub.myInfo.isLegalIdentity(otherSession.counterparty)) {
subFlow(ReceiveFinalityFlow(otherSession))
}
}
}
after the execution of the parent corda-flow AddBankAccount
i get the following error net.corda.core.flows.UnexpectedFlowEndException: Tried to access ended session SessionId(toLong=8223329095323268472) with empty buffer
what do i wrong? can anybody help me?
my stack trace is
net.corda.core.flows.UnexpectedFlowEndException: Tried to access ended session SessionId(toLong=8017581909056924623) with empty buffer
at net.corda.node.services.statemachine.FlowStateMachineImpl.processEventsUntilFlowIsResumed(FlowStateMachineImpl.kt:161) ~[corda-node-4.0-RC01.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.suspend(FlowStateMachineImpl.kt:407) ~[corda-node-4.0-RC01.jar:?]
at net.corda.node.services.statemachine.FlowSessionImpl.receive(FlowSessionImpl.kt:67) ~[corda-node-4.0-RC01.jar:?]
at net.corda.node.services.statemachine.FlowSessionImpl.receive(FlowSessionImpl.kt:71) ~[corda-node-4.0-RC01.jar:?]
at net.corda.core.flows.SignTransactionFlow.call(CollectSignaturesFlow.kt:294) ~[corda-core-4.0-RC01.jar:?]
at net.corda.core.flows.SignTransactionFlow.call(CollectSignaturesFlow.kt:198) ~[corda-core-4.0-RC01.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:290) ~[corda-node-4.0-RC01.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:311) ~[corda-core-4.0-RC01.jar:?]
at com.r3.corda.finance.cash.issuer.service.flows.ReceiveBankAccount.call(ReceiveBankAccount.kt:31) ~[classes/:?]
at com.r3.corda.finance.cash.issuer.service.flows.ReceiveBankAccount.call(ReceiveBankAccount.kt:12) ~[classes/:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:228) ~[corda-node-4.0-RC01.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:45) ~[corda-node-4.0-RC01.jar:?]
at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_131]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[?:1.8.0_131]
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63) ~[corda-node-4.0-RC01.jar:?]
@Suspendable
override fun call(): SignedTransaction {
logger.info("Starting AddBankAccount flow...")
val accountNumber = bankAccount.accountNumber
logger.info("Checking for existence of state for $bankAccount.")
val result = getBankAccountStateByAccountNumber(accountNumber, serviceHub)
if (result != null) {
val linearId = result.state.data.linearId
throw IllegalArgumentException("Bank account $accountNumber already exists with linearId ($linearId).")
}
logger.info("No state for $bankAccount. Adding it.")
progressTracker.currentStep = TX_BUILDING
val bankAccountState = bankAccount.toState(ourIdentity, verifier)
val notary = serviceHub.networkMapCache.notaryIdentities.first()
val verifierSsession = initiateFlow(bankAccountState.verifier)
// The node running this flow is always the only signer.
val command = Command(BankAccountContract.Add(), listOf(ourIdentity.owningKey))
val outputStateAndContract = StateAndContract(bankAccountState, BankAccountContract.CONTRACT_ID)
val unsignedTransaction = TransactionBuilder(notary = notary).withItems(command, outputStateAndContract)
progressTracker.currentStep = TX_SIGNING
val partiallySignedTransaction = serviceHub.signInitialTransaction(unsignedTransaction)
progressTracker.currentStep = TX_VERIFICATION
partiallySignedTransaction.verify(serviceHub)
progressTracker.currentStep = SIGS_GATHERING
val sessionsForFinality = if (serviceHub.myInfo.isLegalIdentity(bankAccountState.verifier)) emptyList() else listOf(verifierSsession)
val fullySignedTx = subFlow(CollectSignaturesFlow(partiallySignedTransaction, sessionsForFinality, SIGS_GATHERING.childProgressTracker()))
progressTracker.currentStep = VERIFYING_SIGS
fullySignedTx.verifyRequiredSignatures()
progressTracker.currentStep = FINALISATION
// Share the added bank account state with the verifier/issuer.
return subFlow(FinalityFlow(fullySignedTx, sessionsForFinality, FINALISATION.childProgressTracker()))
}
ERROR in InitiatorFlow:
flow start AddBankAccount bankAccount: { accountId: "12345", accountName: "Roger's Account", accountNumber: { sortCode: "442200" , accountNumber: "13371337", type: "uk" }, currency: "GBP" }, verifier: Issuer: exception: Collection contains no element matching the predicate.
Fri Jan 18 11:14:03 CET 2019>>> [ERROR] 11:14:03+0100 [pool-8-thread-2] command.CRaSHSession.execute - Error while evaluating request 'flow start AddBankAccount bankAccount: { accountId: "12345", accountName: "Roger's Account", accountNumber: { sortCode: "442200" , accountNumber: "13371337", type: "uk" }, currency: "GBP" }, verifier: Issuer' flow start AddBankAccount bankAccount: { accountId: "12345", accountName: "Roger's Account", accountNumber: { sortCode: "442200" , accountNumber: "13371337", type: "uk" }, currency: "GBP" }, verifier: Issuer: exception: Collection contains no element matching the predicate. [errorCode=hf0q78, moreInformationAt=https://errors.corda.net/OS/4.0-RC01/hf0q78]
WARNs in InitiatorFlow:
[WARN] 11:14:07+0100 [rpc-client-observation-pool-1] internal.RPCClientProxyHandler.onRemoval - A hot observable returned from an RPC was never subscribed to. This wastes server-side resources because it was queueing observations for retrieval. It is being closed now, but please adjust your code to call .notUsed() on the observable to close it explicitly. (Java users: subscribe to it then unsubscribe). If you aren't sure where the leak is coming from, set -Dnet.corda.client.rpc.trackRpcCallSites=true on the JVM command line and you will get a stack trace with this warning.
[WARN] 11:14:07+0100 [rpc-client-observation-pool-1] internal.RPCClientProxyHandler.onRemoval - A hot observable returned from an RPC was never subscribed to. This wastes server-side resources because it was queueing observations for retrieval. It is being closed now, but please adjust your code to call .notUsed() on the observable to close it explicitly. (Java users: subscribe to it then unsubscribe). If you aren't sure where the leak is coming from, set -Dnet.corda.client.rpc.trackRpcCallSites=true on the JVM command line and you will get a stack trace with this warning.
[WARN] 11:14:07+0100 [rpc-client-observation-pool-1] internal.RPCClientProxyHandler.onRemoval - A hot observable returned from an RPC was never subscribed to. This wastes server-side resources because it was queueing observations for retrieval. It is being closed now, but please adjust your code to call .notUsed() on the observable to close it explicitly. (Java users: subscribe to it then unsubscribe). If you aren't sure where the leak is coming from, set -Dnet.corda.client.rpc.trackRpcCallSites=true on the JVM command line and you will get a stack trace with this warning.
回答1:
You will have to add key of bankAccountState.verifier to command.
In your initiator flow change command from:
val command = Command(BankAccountContract.Add(), listOf(ourIdentity.owningKey))
to:
val command = Command(BankAccountContract.Add(), listOf(ourIdentity.owningKey,bankAccountState.verifier.owningKey))
来源:https://stackoverflow.com/questions/54235774/net-corda-core-flows-unexpectedflowendexception-tried-to-access-ended-session-s