关闭devMode后使用自定义证书启动Corda节点遇问题及咨询
问题背景
我们在关闭devMode=true,使用自行生成的非Corda节点证书启动Corda节点时遇到了启动错误,操作步骤如下:
- 按照官方流程生成证书
- 将证书复制到
/certificates目录 - 删除
resources目录下的cordadevcakeys.jks和cordatruststore.jks
启动节点时抛出错误:
Exception during node startup {} java.lang.IllegalArgumentException: Couldn't find network parameters file and compatibility zone wasn't configured/isn't reachable at net.corda.node.internal.NetworkParametersReader.retrieveNetworkParameters(NetworkParametersReader.kt:53) ~[corda-node-corda-4.0-SNAPSHOT.jar:?] at net.corda.node.internal.NetworkParametersReader.access$retrieveNetworkParameters(NetworkParametersReader.kt:17) ~[corda-node-corda-4.0-SNAPSHOT.jar:?] at net.corda.node.internal.NetworkParametersReader$networkParameters$2.invoke(NetworkParametersReader.kt:26) ~[corda-node-corda-4.0-SNAPSHOT.jar:?] at
如果保留resources目录下的cordadevcakeys.jks和cordatruststore.jks,节点可以正常启动。
问题解答
1. 上述场景是否需要配置compatibility zone url?
没错,必须配置。当devMode=false时,节点不再依赖本地开发环境的默认配置,而是需要连接到可信的兼容性区域(CZ)来获取核心的网络参数、验证身份合法性,以及同步网络拓扑。你遇到的启动错误,本质就是节点找不到网络参数的来源——既没有本地预存的参数文件,又没配置CZ URL去在线获取。
2. 若需要,配置该url的要求是什么?
- 必须使用HTTPS协议:因为涉及敏感的证书请求、身份验证数据和网络参数传输,HTTPS能确保通信加密和数据完整性
- URL指向的Doorman服务必须是网络中可信且运行正常的兼容性区域入口节点
- 节点必须信任该Doorman服务的SSL证书:可以通过将其根证书加入节点的信任库来实现
3. Corda Doorman通过何种方式发送证书?HTTPS/HTTP GET还是其他协议?
Doorman通过HTTPS POST请求处理证书相关操作。节点会向Doorman的特定端点发送证书签名请求(CSR),Doorman验证请求合法后,会返回签名后的完整证书链,整个过程都是加密的HTTPS通信,不会用明文的HTTP。
4. 请解释devmode=false、兼容性区域场景下,节点启动对resources目录下cordadevcakeys.jks和cordatruststore.jks的依赖关系?
当devMode=false时,节点完全不应该依赖这两个文件——它们是开发模式下用于快速启动的默认密钥库和信任库。你删除它们后启动失败,本质原因不是依赖这两个文件,而是你没正确配置兼容性区域,节点退而求其次尝试使用开发模式的默认资源,但找不到才报错。正常的生产/非开发模式下,节点应该使用你自行生成的证书,并通过配置的CZ获取网络参数,完全不需要这两个开发环境文件。
5. 请解释network-parameters的作用及结构?
- 作用:Network Parameters是整个Corda网络的全局规则配置,所有节点必须严格遵守,确保网络的一致性和兼容性。核心作用包括:
- 限定节点必须运行的最低Corda版本
- 限制交易、消息的最大大小
- 定义网络认可的公证人节点
- 指定允许部署的合约实现列表等
- 结构:它是一个Protobuf序列化的结构,核心字段有:
minimumPlatformVersion: 节点必须满足的最低Corda版本maxMessageSize/maxTransactionSize: 消息、交易的最大字节限制notaries: 网络中授权的公证人节点信息列表epoch: 参数的版本号,每次更新规则时递增whitelistedContractImplementations: 网络允许的合约实现清单
6. 我们未找到network-parameters的规范用法及文档,请协助说明?
Network Parameters的生命周期和使用逻辑是这样的:
- 由兼容性区域的管理员生成初始参数集,并用CZ的根CA密钥签名,确保权威性
- 节点启动时,从Doorman或网络映射服务获取最新的签名参数集
- 节点验证参数的签名合法性(确认是可信的CZ发布的)
- 节点必须严格遵守参数中的所有规则,否则无法加入网络
- 当需要更新网络规则时,CZ管理员会发布新的参数集(epoch递增),节点会自动或手动接受并切换到新参数
7. 配置兼容性区域与配置网络映射服务是否不同?
是的,两者完全不同:
- 兼容性区域(CZ):是一个包含Doorman服务和网络映射服务的整体服务集群,负责节点身份验证、证书管理、网络参数分发以及网络拓扑同步
- 网络映射服务:是CZ的一部分,专门负责维护和提供网络中所有节点的拓扑信息(node-info)
- 配置时需要分别指定
doormanURL(CZ的身份验证入口)和networkMapURL(拓扑信息入口)
8. Doorman与网络映射服务不同,且Doorman是离线实体,证书通过带外方式生成和分发,该理解是否正确?
这个理解有两处不准确:
- Doorman和网络映射服务确实是不同的服务,职责不同(Doorman管身份验证/证书,网络映射管拓扑)
- 但Doorman不是离线实体,它是在线服务,节点必须能连接到它来完成证书请求、身份验证和网络参数获取
- 证书可以通过带外方式分发(比如你自行生成后复制到节点),但标准流程是节点向Doorman发送CSR,由Doorman在线签名并返回证书链
9. network-map是单个文件还是分散的node-info文件?若是单个文件,请说明格式和编码;/network-map/node-info/{hash}中的hash代表什么?
- Network Map本身是单个的Protobuf二进制序列化文件,包含三个核心内容:网络中所有node-info的哈希值列表、当前网络参数的哈希值、参数更新信息
/network-map/node-info/{hash}中的hash是对应node-info文件的安全哈希值(由Corda的SecureHash算法生成)。节点先获取Network Map得到所有node-info的哈希,再通过这个端点下载具体的node-info文件,哈希用于验证文件的完整性和真实性,防止被篡改
10. 请解释/network-map/ack-parameters的用途?
这个端点用于节点向网络映射服务确认自己已经接受了新的网络参数集。当CZ发布了更新的网络参数(epoch递增),节点下载并验证签名合法性后,需要向该端点发送确认请求,告知网络自己已经切换到新参数,这样网络映射服务可以跟踪哪些节点已经完成参数更新,确保整个网络的规则一致性。
11. 在官方配置文件示例中,compatibilityZoneUrl使用“https://”协议,该示例是否有误?
没有错误。兼容性区域的Doorman服务必须使用HTTPS协议,因为涉及敏感的证书请求、身份验证数据和网络参数传输,HTTPS能确保通信的加密和完整性,防止数据被篡改或窃听,这是生产环境的强制要求。
12. 如何创建network-parameters文件?已知文件大致内容,但不清楚具体编码;该文件是否由独立程序创建?由谁签名?节点操作员是否需每次手动接受新的网络参数集?如何获取/network-map/network-parameters/{hash}中的hash值?
- 创建与编码:Network Parameters文件可以通过Corda官方提供的
network-parameters-generator工具生成,采用Protobuf二进制编码,也可以序列化为JSON格式用于调试,但生产环境必须使用二进制格式 - 签名:必须由兼容性区域的根CA密钥签名,确保参数的权威性和不可篡改性
- 接受新参数:默认情况下节点会自动接受合法的新参数集,也可以通过配置
networkParametersAutoAcceptEnabled=false让操作员手动确认 - 获取hash值:有两种方式:
- 从Network Map文件中读取
networkParameterHash字段 - 使用Corda的哈希工具直接计算生成的网络参数文件的
SecureHash值
- 从Network Map文件中读取
13. 请查看附件图片(https://i.sstatic.net/rtCqs.jpg),判断我们对流程的理解是否正确?
从图片展示的流程来看,你的理解完全正确:
- 节点向Doorman发送证书签名请求(CSR)
- Doorman验证请求合法性后返回签名后的证书链
- 节点向网络映射服务注册自己的node-info
- 节点从网络映射服务获取Network Map和其他节点的node-info
- 节点与其他节点建立安全连接
这个流程完全符合Corda节点加入兼容性区域的标准步骤。
14. 请明确节点发送证书请求的端点?我们在示例配置中看到:
networkServices : { doormanURL = "https://registration.corda.net" networkMapURL = "https://cz.corda.net" }
请说明Doorman URL提供的其他REST端点,是否包含/certificate?
- 节点发送证书请求的端点是
{doormanURL}/certificate(POST请求),节点会将CSR和相关身份信息发送到这个端点 - Doorman提供的其他核心REST端点包括:
/health: 健康检查端点,用于验证Doorman服务是否正常运行/network-parameters: 获取最新的网络参数集/ack-node-info: 确认节点已经完成node-info注册
15. 由于network-map结构如下:
data class NetworkMap( val nodeInfoHashes: List<SecureHash>, val networkParameterHash: SecureHash, val parametersUpdate: ParametersUpdate? )
且不包含nodeinfo,请问以下流程是否正确?
(1) 节点先从network-map获取所有nodeinfo的哈希值
(2) 节点逐个下载所有nodeInfo
请说明nodeInfo何时上传?若节点是第一个节点,network-map为空,节点是否会启动失败?
- 这个流程完全正确:节点先获取Network Map得到所有node-info的哈希列表,再通过
/network-map/node-info/{hash}端点逐个下载具体的node-info文件 - nodeInfo上传时机:节点启动完成并完成身份验证后,会将自己的node-info发送到网络映射服务的
/node-info端点进行注册 - 第一个节点的情况:不会启动失败。当网络中没有其他节点时,Network Map的
nodeInfoHashes列表为空,但节点只需要获取到合法的网络参数就能正常启动——它会注册自己的node-info,此时Network Map会更新包含这个节点的哈希。节点启动不依赖其他节点的存在。
内容的提问来源于stack exchange,提问作者Mahesh Govind

