Corda 4.5.8中f2流执行报错:NotaryFlow$Client未注册求助
问题分析与解决方案
场景与错误现象
在部署了2个Corda节点(A、B)和1个公证节点的环境中,存在两个业务流:
f1:仅在节点A运行,创建本地存储的交易(无跨节点交互),运行正常。f2:同样在节点A启动,用于修改f1插入的状态s1、s2...——输入为这些现有状态,输出为修改后的s1'、s2'...,同时新增1个额外输出状态,交易最终同步给节点B。
执行f2时出现以下错误:
- 节点A与公证节点日志报错:
net.corda.core.flows.UnexpectedFlowEndException: net.corda.core.flows.NotaryFlow$Client is not registered - 节点B日志报错:
net.corda.core.flows.UnexpectedFlowEndException: Counter-flow errored
本地Mock网络测试无异常,使用Corda版本为4.5.8,f2流的交易创建代码片段如下:
val txBuilder = TransactionBuilder(notary) .addOutputState(additionalState, "CustomContract.ID") .addCommand( Command( contract, additionalState.participants.map { it.owningKey }) ) existingStates.forEach { txBuilder.addInputState(serviceHub.toStateAndRef<CustomState>(it.ref)) } existingStatesModified.forEach { txBuilder.addOutputState(it, "CustomContract.ID") } // Stage 2. progressTracker.currentStep = VERIFYING_TRANSACTION // Verify that the transaction is valid. txBuilder.verify(serviceHub) // Stage 3. progressTracker.currentStep = SIGNING_TRANSACTION // Sign the transaction. val partSignedTx = serviceHub.signInitialTransaction(txBuilder) // Stage 4. progressTracker.currentStep = GATHERING_SIGS // Send the state to the counterparty, and receive it back with their signature. val otherPartySessions = counterParties.map { initiateFlow(it!!) } val fullySignedTx = subFlow(CollectSignaturesFlow(partSignedTx, otherPartySessions, GATHERING_SIGS.childProgressTracker())) // Stage 5. progressTracker.currentStep = FINALISING_TRANSACTION // Notarise and record the transaction in both parties' vaults. require(insertEvent(insuranceEventState.fullEvent)) { "Unable to insert event data into the triple store." } return subFlow(FinalityFlow(fullySignedTx, otherPartySessions, FINALISING_TRANSACTION.childProgressTracker()))
错误原因排查方向
这个错误通常由以下几类问题导致:
- 公证节点内置流未正确注册:
NotaryFlow$Client是Corda核心内置流,正常会自动注册,若公证节点的Jar包缺失、配置错误或启动异常,会导致流注册失败。 - 交易公证一致性问题:
f1创建的状态使用的公证与f2中TransactionBuilder指定的公证不一致,或输入状态中存在不同公证的状态,会触发NotaryFlow调用异常。 - 节点A/B的流注册异常:自定义流的注解缺失(如
@InitiatingFlow/@InitiatedBy)、Cordapp Jar包不完整或版本冲突,可能影响内置流的正常调用。 - FinalityFlow调用前流程终止:
insertEvent操作失败会触发require断言,导致流程提前终止,后续的FinalityFlow无法正常执行,进而引发NotaryFlow相关异常。
修复步骤
1. 验证公证节点配置与完整性
- 检查公证节点的
node.conf,确认notary配置正确(如validating类型),节点已正常启动且无启动报错。 - 确认公证节点的
cordapps和lib目录下Jar包完整,无corda-core、corda-node等核心依赖缺失。
2. 核对交易公证一致性
- 对比
f1创建状态时使用的公证,与f2中TransactionBuilder(notary)的notary对象是否为同一节点(可打印legalIdentity确认)。 - 检查所有输入状态
s1、s2...的公证信息,确保全部与f2使用的公证一致。
3. 检查节点A/B的流注册与Jar包
- 确认节点A/B的
cordapps目录下包含完整的合约与流Jar包,无版本冲突。 - 检查
f2流是否添加了@InitiatingFlow注解,对应的接收流(若自定义)是否添加了@InitiatedBy注解并正确打包。
4. 修复FinalityFlow调用前的潜在问题
- 排查
insertEvent操作是否存在失败场景,可添加日志打印其执行结果,避免因断言失败导致流程提前终止。 - 确认
counterParties正确包含节点B的身份,initiateFlow未抛出异常(可添加日志打印会话对象)。
5. 补充日志排查
- 在
f2流的关键步骤(如交易构建完成、签名后、收集签名后)添加日志,打印交易的输入输出状态、公证信息、会话对象,确认参数正确性。 - 查看公证节点的详细日志,获取更具体的错误上下文(如交易验证失败、权限问题等)。
内容的提问来源于stack exchange,提问作者SilverTear
相关产品推荐
相关产品推荐

