微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Corda-在所有参与者的保管库中记录状态之前,确定性流程是否结束?

如何解决Corda-在所有参与者的保管库中记录状态之前,确定性流程是否结束?

最近,我遇到了一个问题,当流程在发起者的节点上结束时,立即在所有事务参与者节点的保管库中查询事务的输出状态时,发现该状态仅存在在发起者的节点上,并且仅在一段时间后才出现在其他参与者节点的保管库中。 阅读文档here“将交易发送给交易对手进行记录”,并没有说它将等到交易对手成功将交易及其状态记录到其保管库中后,这种情况才能确认该问题我面对的实际上是Corda的实现方式,而不是bug左右。

另一方面,在没有确保在交易对手节点上一切都成功完成并且所有状态都写在其保管库中的情况下,结束流程似乎不合逻辑。

我也查看了代码,并在ServiceHubInternal中使用了此方法,该方法似乎负责将状态记录到Vault中。

fun recordTransactions(statesToRecord: StatesToRecord,txs: Collection<SignedTransaction>,validatedTransactions: WritableTransactionStorage,stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage,vaultService: VaultServiceInternal,database: CordaPersistence) {

        database.transaction {
            require(txs.isNotEmpty()) { "No transactions passed in for recording" }

            val orderedTxs = topologicalSort(txs)
            val (recordedTransactions,prevIoUsLyseenTxs) = if (statesToRecord != StatesToRecord.ALL_VISIBLE) {
                orderedTxs.filter(validatedTransactions::addTransaction) to emptyList()
            } else {
                orderedTxs.partition(validatedTransactions::addTransaction)
            }
            val stateMachineRunId = FlowStateMachineImpl.currentStateMachine()?.id
            if (stateMachineRunId != null) {
                recordedTransactions.forEach {
                    stateMachineRecordedTransactionMapping.addMapping(stateMachineRunId,it.id)
                }
            } else {
                log.warn("Transactions recorded from outside of a state machine")
            }

            vaultService.notifyAll(statesToRecord,recordedTransactions.map { it.coreTransaction },prevIoUsLyseenTxs.map { it.coreTransaction })
        }
    }

在我看来,这种方法并没有执行异步操作,所以我真的很困惑。 所以实际的问题是:

Corda中的发起方流实际上是等待直到所有相关状态记录在所有参与者节点的保管库中才完成,还是在将状态发送给参与者节点进行记录之后立即完成,而无需等待来自确认的确认他们表示状态已被记录?

已编辑

因此,如果Corda认情况下不等待交易对手流将状态存储在其保管库中,但是我的实现仍然需要此行为,那么实现以下内容将是一个好的解决方案:

在发起方流程的最后,在从方法调用receiveAll返回以挂起并等待之前,然后在接收方流程的最后,在从方法调用返回之前,使用{{1 }}等到感兴趣的状态记录在Vault中后,无论何时,只要调用trackBy即可通知发起者的sendAll方法。并且只有当启动者已经收到所有接收者的确认后,才能完成启动者的流程。

解决此问题是否正常?它有没有您能想到的缺点或副作用?

解决方法

Corda能够处理您的情况,实际上在Error handling behaviour部分的here中有解释;以下是摘录,但我建议阅读全文:

要从这种情况下恢复,接收者的确定性处理程序将自动发送到Flow Hospital,在节点重启后,它会被暂停并从最后一个检查点重试

,

发起方流程不负责在响应者的保险库中存储状态。因此,由于响应者已经检查了交易并提供了签名,因此没有来自响应者的存储确认。因此,从发起方的角度来看,一旦对交易进行了公证并存储在其一边,一切都很好,如上一条评论中所述,应由响应方来管理其存储阶段中的错误。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。