我正在测试具有区域约束的Corda 4.1开源,我有4个节点,分别是Node A,Node B,Node C和Notary(Notary是Corda 4.1的CE版本)
我运行 IssueFlow 来创建从节点B到节点A的 StateA 。 并在提交事务节点A的子流程后的IssueFlow.Responder中,通过 TestFlow 来更新 StateA ,这会将Node C添加到 StateA 的参与者中
这是IssueFlow.Responder中的代码
@InitiatedBy(IssueFlow.Initiator::class)
class Responder(val otherFlow: FlowSession) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
val flow = object : SignTransactionFlow(otherFlow) {
@Suspendable
override fun checkTransaction(stx: SignedTransaction) {
// Custom validation here
}
}
val stx = subFlow(flow)
val waitForLedgerCommit = subFlow(ReceiveFinalityFlow(otherFlow, stx.id))
executableAfterCommit(waitForLedgerCommit)
return waitForLedgerCommit
}
@Suspendable
private fun executableAfterCommit(stx: SignedTransaction) {
val listOfStateA = stx.tx.outputsOfType<StateA>()
require(listOfStateA.size == 1) { "Only one document of StateA is allowed in the transaction." }
val stateA = listOfStateA.single()
subFlow(TestFlow.Initiator(listOf(stateA.linearId.id.toString())))
}
}
在TestFlow中,我将更新 StateA 的一些信息,并将Node C添加为其他参与者,但我只希望NodeA和NodeB进行签名。 代码如下:
object TestFlow {
@InitiatingFlow
@StartableByRPC
class Initiator(private val linearId: String) : FlowLogic<SignedTransaction>() {
override val progressTracker: ProgressTracker()
val window by lazy { TimeWindow.withTolerance(currentClock.instant(), 30.minutes) }
@Suspendable
override fun call(): SignedTransaction {
val stx = collectSignatures(verifyAndSign(build()))
val sessions = transaction.sessionsOfParticipants()
return subFlow(FinalityFlow(stx, sessions))
}
private fun build(): TransactionBuilder {
val statesIn = queryByLinear(listOf(linearId.toUUID())).single()
val stateOut = stateIn.changeData("field1").addParticipants(NodeC)
val result = TransactionBuilder(firstNotary).apply {
// Add inputs
withItems(statesIn)
// Add outputs
withItems(StateAndContract(stateOut, StateAContract.CONTRACT_ID))
// Signer only NodeA and NodeB
val listOfSigner = listOf(statesIn.state.data, stateOut)
.selectKeysOf(addNodeA = true, addNodeB = true)
.toList()
// Add commands
addCommand(StateAContract.Commands.Test(), listOfSigner)
setTimeWindow(window)
}
return result.toLedgerTransaction(serviceHub)
}
private fun verifyAndSign(transaction: TransactionBuilder): SignedTransaction {
transaction.verify(serviceHub)
return serviceHub.signInitialTransaction(transaction)
}
@Suspendable
private fun collectSignatures(transaction: SignedTransaction): SignedTransaction {
val signers = excludeNotary(groupPublicKeysByWellKnownParty(serviceHub, transaction.getMissingSigners()), transaction).map { it.key }
return subFlow(CollectSignatureInitiator(transaction, signers))
}
}
@InitiatedBy(Initiator::class)
class Responder(private val otherFlow: FlowSession) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
return subFlow(ReceiveFinalityFlow(otherFlow))
}
}
/**
* Collect signature initiating flow
*/
@InitiatingFlow
class CollectSignatureInitiator(private val transaction: SignedTransaction, private val signers: List<Party>) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
val sessions = signers.map { initiateFlow(it) }
return subFlow(CollectSignaturesFlow(transaction, sessions))
}
}
/**
* Collect signature responder flow
*/
@InitiatedBy(CollectSignatureInitiator::class)
class CollectSignatureResponder(private val session: FlowSession) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
return subFlow(object : SignTransactionFlow(session) {
override fun checkTransaction(stx: SignedTransaction) {
subFlow(ValidateDocument(session, stx))
return
}
})
}
}
}
并且TestFlow在Node C中引发错误,如下所示:
[INFO ] 2019-09-27T01:54:42,534Z [Node thread-1] corda.flow.call - Transaction dependencies resolution completed. {fiber-id=10000001, flow-id=1413cfc2-c522-45be-90d3-ce593ba3db91, invocation_id=cb808503-85c2-4c8c-afb7-3d1996f4fc02, invocation_timestamp=2019-09-27T01:52:36.071Z, origin=OU=NodeA, O=NodeA, L=Bangkok, C=TH, session_id=cb808503-85c2-4c8c-afb7-3d1996f4fc02, session_timestamp=2019-09-27T01:52:36.071Z, thread-id=205, tx_id=A083E2C3F0AA98DFCE5D0FD02420EF1A4947FEAEACE2AB1226FF89CA606D19B3}
[INFO ] 2019-09-27T01:54:42,814Z [Node thread-1] corda.flow.call - Successfully received fully signed tx. Sending it to the vault for processing. {fiber-id=10000001, flow-id=1413cfc2-c522-45be-90d3-ce593ba3db91, invocation_id=cb808503-85c2-4c8c-afb7-3d1996f4fc02, invocation_timestamp=2019-09-27T01:52:36.071Z, origin=OU=NodeA, O=NodeA, L=Bangkok, C=TH, session_id=cb808503-85c2-4c8c-afb7-3d1996f4fc02, session_timestamp=2019-09-27T01:52:36.071Z, thread-id=205, tx_id=A083E2C3F0AA98DFCE5D0FD02420EF1A4947FEAEACE2AB1226FF89CA606D19B3}
[INFO ] 2019-09-27T01:54:42,987Z [Node thread-1] corda.flow.run - Flow raised an error: org.hibernate.HibernateException: Flush during cascade is dangerous. Sending it to flow hospital to be triaged. {fiber-id=10000001, flow-id=1413cfc2-c522-45be-90d3-ce593ba3db91, invocation_id=cb808503-85c2-4c8c-afb7-3d1996f4fc02, invocation_timestamp=2019-09-27T01:52:36.071Z, origin=OU=NodeA, O=NodeA, L=Bangkok, C=TH, session_id=cb808503-85c2-4c8c-afb7-3d1996f4fc02, session_timestamp=2019-09-27T01:52:36.071Z, thread-id=205, tx_id=A083E2C3F0AA98DFCE5D0FD02420EF1A4947FEAEACE2AB1226FF89CA606D19B3}
[INFO ] 2019-09-27T01:54:42,999Z [Node thread-1] statemachine.StaffedFlowHospital.flowErrored - Flow [1413cfc2-c522-45be-90d3-ce593ba3db91] admitted to hospital in state StateMachineState(checkpoint=Checkpoint(invocationContext=InvocationContext(origin=Peer(party=OU=NodeA, O=NodeA, L=Bangkok, C=TH), trace=Trace(invocationId=cb808503-85c2-4c8c-afb7-3d1996f4fc02, timestamp: 2019-09-27T01:52:36.071Z, entityType: Invocation, sessionId=cb808503-85c2-4c8c-afb7-3d1996f4fc02, timestamp: 2019-09-27T01:52:36.071Z, entityType: Session), actor=null, externalTrace=null, impersonatedActor=null), ourIdentity=OU=BANK, O=SCB3, L=Bangkok, C=TH, sessions={SessionId(toLong=-2182783777352841143)=Initiated(peerParty=OU=NodeA, O=NodeA, L=Bangkok, C=TH, peerFlowInfo=FlowInfo(flowVersion=1, appName=testflow-1.0), receivedMessages=[], initiatedState=Live(peerSinkSessionId=SessionId(toLong=-3936218859034478298)), errors=[], deduplicationSeed=D--3936218859034478298--368822318982290956)}, subFlowStack=[Inlined(flowClass=class com.corda.test.flows.TestFlow$Responder, subFlowVersion=CoreFlow(platformVersion=4), isEnabledTimedFlow=false)], flowState=Started(flowIORequest=Send(sessionToMessage={FlowSessionImpl(counterparty=OU=NodeA, O=NodeA, L=Bangkok, C=TH, sourceSessionId=SessionId(toLong=-2182783777352841143))=768AED61FD2A58D74D7316731407E0600065080E1F3E6397EE4FA5AEFEE79295}), frozenFiber=6C3A73148E4E786591224DA1A0BDCADD704073C8A70CE425769DE7576F43735B), errorState=Clean, numberOfSuspends=5), flowLogic=com.corda.test.flows.TestFlow$Responder@1ad039f4, pendingDeduplicationHandlers=[], isFlowResumed=true, isTransactionTracked=false, isAnyCheckpointPersisted=true, isStartIdempotent=false, isRemoved=false, senderUUID=f5784837-d7a3-45e8-8b4c-9cf286f080b8) {fiber-id=10000001, flow-id=1413cfc2-c522-45be-90d3-ce593ba3db91, invocation_id=cb808503-85c2-4c8c-afb7-3d1996f4fc02, invocation_timestamp=2019-09-27T01:52:36.071Z, origin=OU=NodeA, O=NodeA, L=Bangkok, C=TH, session_id=cb808503-85c2-4c8c-afb7-3d1996f4fc02, session_timestamp=2019-09-27T01:52:36.071Z, thread-id=205, tx_id=A083E2C3F0AA98DFCE5D0FD02420EF1A4947FEAEACE2AB1226FF89CA606D19B3}
[INFO ] 2019-09-27T01:54:43,005Z [Node thread-1] statemachine.StaffedFlowHospital.invoke - Error 1 of 1: {fiber-id=10000001, flow-id=1413cfc2-c522-45be-90d3-ce593ba3db91, invocation_id=cb808503-85c2-4c8c-afb7-3d1996f4fc02, invocation_timestamp=2019-09-27T01:52:36.071Z, origin=OU=NodeA, O=NodeA, L=Bangkok, C=TH, session_id=cb808503-85c2-4c8c-afb7-3d1996f4fc02, session_timestamp=2019-09-27T01:52:36.071Z, thread-id=205, tx_id=A083E2C3F0AA98DFCE5D0FD02420EF1A4947FEAEACE2AB1226FF89CA606D19B3}
javax.persistence.PersistenceException: org.hibernate.HibernateException: Flush during cascade is dangerous
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1460) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1440) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at net.corda.node.utilities.AppendOnlyPersistentMapBase.loadValue(AppendOnlyPersistentMap.kt:145) ~[corda-node-4.1.jar:?]
at net.corda.node.utilities.AppendOnlyPersistentMapBase.access$loadValue(AppendOnlyPersistentMap.kt:22) ~[corda-node-4.1.jar:?]
at net.corda.node.utilities.AppendOnlyPersistentMapBase$transactionalLoadValue$3.invoke(AppendOnlyPersistentMap.kt:160) ~[corda-node-4.1.jar:?]
at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional$Unknown$valueWithoutIsolationDelegate$1.invoke(AppendOnlyPersistentMap.kt:251) ~[corda-node-4.1.jar:?]
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional$Unknown.isPresent(AppendOnlyPersistentMap.kt:249) ~[corda-node-4.1.jar:?]
at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional.orElse(AppendOnlyPersistentMap.kt:222) ~[corda-node-4.1.jar:?]
at net.corda.node.utilities.AppendOnlyPersistentMapBase.get(AppendOnlyPersistentMap.kt:40) ~[corda-node-4.1.jar:?]
at net.corda.node.services.identity.PersistentIdentityService$certificateFromCordaX500Name$1.invoke(PersistentIdentityService.kt:165) ~[corda-node-4.1.jar:?]
at net.corda.node.services.identity.PersistentIdentityService$certificateFromCordaX500Name$1.invoke(PersistentIdentityService.kt:33) ~[corda-node-4.1.jar:?]
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:224) ~[corda-node-api-4.1.jar:?]
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:204) ~[corda-node-api-4.1.jar:?]
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:210) ~[corda-node-api-4.1.jar:?]
at net.corda.node.services.identity.PersistentIdentityService.certificateFromCordaX500Name(PersistentIdentityService.kt:164) ~[corda-node-4.1.jar:?]
at net.corda.node.services.identity.PersistentIdentityService.wellKnownPartyFromX500Name(PersistentIdentityService.kt:175) ~[corda-node-4.1.jar:?]
at net.corda.core.node.services.IdentityService$DefaultImpls.wellKnownPartyFromAnonymous(IdentityService.kt:103) ~[corda-core-4.1.jar:?]
at net.corda.node.services.api.IdentityServiceInternal$DefaultImpls.wellKnownPartyFromAnonymous(IdentityServiceInternal.kt) ~[corda-node-4.1.jar:?]
at net.corda.node.services.identity.PersistentIdentityService$wellKnownPartyFromAnonymous$1.invoke(PersistentIdentityService.kt:184) ~[corda-node-4.1.jar:?]
at net.corda.node.services.identity.PersistentIdentityService$wellKnownPartyFromAnonymous$1.invoke(PersistentIdentityService.kt:33) ~[corda-node-4.1.jar:?]
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:224) ~[corda-node-api-4.1.jar:?]
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:204) ~[corda-node-api-4.1.jar:?]
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:210) ~[corda-node-api-4.1.jar:?]
at net.corda.node.services.identity.PersistentIdentityService.wellKnownPartyFromAnonymous(PersistentIdentityService.kt:184) ~[corda-node-4.1.jar:?]
at net.corda.node.internal.AbstractNode$database$2.invoke(AbstractNode.kt:158) ~[corda-node-4.1.jar:?]
at net.corda.node.internal.AbstractNode$database$2.invoke(AbstractNode.kt:120) ~[corda-node-4.1.jar:?]
at net.corda.node.services.persistence.AbstractPartyToX500NameAsStringConverter.convertToDatabaseColumn(AbstractPartyToX500NameAsStringConverter.kt:23) ~[corda-node-4.1.jar:?]
at net.corda.node.services.persistence.AbstractPartyToX500NameAsStringConverter.convertToDatabaseColumn(AbstractPartyToX500NameAsStringConverter.kt:15) ~[corda-node-4.1.jar:?]
at org.hibernate.metamodel.model.convert.internal.JpaAttributeConverterImpl.toRelationalValue(JpaAttributeConverterImpl.java:50) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter$1.bind(AttributeConverterSqlTypeDescriptorAdapter.java:78) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:280) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:275) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:39) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2868) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3162) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3686) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:90) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.spi.ActionQueue.executeInserts(ActionQueue.java:461) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:258) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:359) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:292) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:200) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:131) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:192) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:824) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:791) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:298) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:471) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:396) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:197) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:504) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:436) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:399) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:197) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:130) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:486) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:200) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:143) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:192) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:62) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:800) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:785) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
at net.corda.node.services.schema.PersistentStateService.persistStatesWithSchema$node(PersistentStateService.kt:48) ~[corda-node-4.1.jar:?]
at net.corda.node.services.schema.PersistentStateService.persist(PersistentStateService.kt:40) ~[corda-node-4.1.jar:?]
at net.corda.node.services.vault.NodeVaultService.processAndNotify(NodeVaultService.kt:364) ~[corda-node-4.1.jar:?]
at net.corda.node.services.vault.NodeVaultService.access$processAndNotify(NodeVaultService.kt:51) ~[corda-node-4.1.jar:?]
at net.corda.node.services.vault.NodeVaultService$notifyAll$1.invoke(NodeVaultService.kt:213) ~[corda-node-4.1.jar:?]
at net.corda.node.services.vault.NodeVaultService.notifyAll(NodeVaultService.kt:223) ~[corda-node-4.1.jar:?]
at net.corda.node.services.api.ServiceHubInternal$Companion$recordTransactions$1.invoke(ServiceHubInternal.kt:106) ~[corda-node-4.1.jar:?]
at net.corda.node.services.api.ServiceHubInternal$Companion$recordTransactions$1.invoke(ServiceHubInternal.kt:51) ~[corda-node-4.1.jar:?]
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:224) ~[corda-node-api-4.1.jar:?]
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:204) ~[corda-node-api-4.1.jar:?]
at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:210) ~[corda-node-api-4.1.jar:?]
at net.corda.node.services.api.ServiceHubInternal$Companion.recordTransactions(ServiceHubInternal.kt:60) ~[corda-node-4.1.jar:?]
at net.corda.node.services.api.ServiceHubInternal$DefaultImpls.recordTransactions(ServiceHubInternal.kt:132) ~[corda-node-4.1.jar:?]
at net.corda.node.internal.AbstractNode$ServiceHubInternalImpl.recordTransactions(AbstractNode.kt:962) ~[corda-node-4.1.jar:?]
at net.corda.core.flows.ReceiveTransactionFlow.call(ReceiveTransactionFlow.kt:62) ~[corda-core-4.1.jar:?]
at net.corda.core.flows.ReceiveTransactionFlow.call(ReceiveTransactionFlow.kt:28) ~[corda-core-4.1.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:329) ~[corda-node-4.1.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:314) ~[corda-core-4.1.jar:?]
at net.corda.core.flows.ReceiveFinalityFlow.call(FinalityFlow.kt:256) ~[corda-core-4.1.jar:?]
at net.corda.core.flows.ReceiveFinalityFlow.call(FinalityFlow.kt:251) ~[corda-core-4.1.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:329) ~[corda-node-4.1.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:314) ~[corda-core-4.1.jar:?]
at com.corda.test.flows.TestFlow$Responder.call(TestFlow.kt:226) ~[?:?]
at com.corda.test.flows.TestFlow$Responder.call(TestFlow.kt:221) ~[?:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:269) ~[corda-node-4.1.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:45) ~[corda-node-4.1.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_222]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_222]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_222]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[?:1.8.0_222]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_222]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_222]
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63) ~[corda-node-4.1.jar:?]
Caused by: org.hibernate.HibernateException: Flush during cascade is dangerous
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1449) ~[hibernate-core-5.3.6.Final.jar:5.3.6.Final]
... 104 more
现在我要解决的问题是去链上数据库并截断下表
- node_info_party_cert
- node_link_nodeinfo_party
- node_info_hosts
- node_infos
截断这些表后,我重新启动节点C,然后使其从节点检查点恢复,一切正常。
有时错误在节点B和节点C上都发生。
我在CE环境中使用了相同的代码并进行了测试,但没有发现此错误。
问题是
答案 0 :(得分:0)
最新版本的Corda OS 4.3已解决此问题。
您可以在build.gradle中更新依赖项,并将其指向更高版本的Corda。