Corda节点为同一LinearState生成不同Linear ID问题排查
问题根源分析与解决方案
你遇到的两个节点同一状态linearId不一致的问题,核心原因是状态类中linearId的初始化方式错误,导致接收节点反序列化时重新生成了新的UniqueIdentifier实例。
为什么会出现这个问题?
在Corda 3.1中,当状态被序列化传输到其他节点后,反序列化过程会重新创建PurchaseOrderState对象。你当前的代码是在类体内直接初始化linearId:
override val linearId : UniqueIdentifier = UniqueIdentifier(props.purchaseOrderID)
UniqueIdentifier的构造器在只传入externalId时,会自动生成一个随机UUID作为核心ID。这意味着:
- 发起节点创建状态时生成一个UUID
- 接收节点反序列化时,会再次执行这段初始化代码,生成一个全新的UUID
最终两边的linearId虽然externalId相同,但核心UUID完全不一样,导致整体linearId不一致。
修复方案
把linearId作为PurchaseOrderState的构造函数参数传入,让发起节点生成的linearId被完整序列化并传输到接收节点,而不是在每个节点重新生成。
修改后的状态定义
data class PurchaseOrderState( val buyer: Party, val seller: Party, val props: PurchaseOrderProperties, val invoiceAssigned: Boolean, override val linearId: UniqueIdentifier // 作为构造参数传入 ) : LinearState { override val participants = listOf(buyer, seller) // 可选:添加辅助构造函数,简化状态创建 constructor( buyer: Party, seller: Party, props: PurchaseOrderProperties, invoiceAssigned: Boolean ) : this(buyer, seller, props, invoiceAssigned, UniqueIdentifier(props.purchaseOrderID)) } @CordaSerializable data class PurchaseOrderProperties( val purchaseOrderID: String, val invoiceStateReference: StateRef? )
调整测试代码中的状态创建
你可以直接使用辅助构造函数创建状态,无需手动处理linearId:
val postate = PurchaseOrderState( a.services.myInfo.singleIdentity(), b.services.myInfo.singleIdentity(), props, false )
额外注意点
测试代码中还有一处拼写错误需要修正,否则可能导致流程无法正确注册:
// 原错误代码 listOf(a, b).forEach{ it.registerInitiatedFlow(PurchaseOrderFlow.SendPurcahseOrder::class.java)} // 修正后 listOf(a, b).forEach{ it.registerInitiatedFlow(PurchaseOrderFlow.SendPurchaseOrder::class.java)}
修改完成后,发起节点生成的linearId会被完整序列化传输,两个节点的同一份状态就会拥有完全一致的linearId了。
内容的提问来源于stack exchange,提问作者nitesh solanki
相关产品推荐
相关产品推荐

