corda - 在同一个 Corda 流程中创建多个交易有什么风险?

标签 corda

在 Cordapp 中,我想更新第二条链作为正常交易的一部分。由于数据在具有不同参与者的两个不同状态中被跟踪,因此这需要在两个事务中完成。

出于讨论的目的,我们有两方 A 和 B。A 向 B 发起事务 1。在接收事务 1 后,B 方启动事务 2 以更新另一个状态。我们如何确保两个事务都成功完成?

有两种方法可以解决这个问题:

  • 发起 subFlow对于事务 2 内联流响应器。
  • 使用 vaultTrack响应已提交的事务 1 并启动 subFlow对于交易 2。

  • 以下是选项 1 的一些示例代码:
    class CustomerIssueFlowResponder(val otherPartyFlow: FlowSession) : FlowLogic<SignedTransaction>() {
        @Suspendable
        override fun call(): SignedTransaction {
            val signTransactionFlow = object : SignTransactionFlow(otherPartyFlow) {
                override fun checkTransaction(stx: SignedTransaction) = requireThat {
                    val output = stx.tx.outputs.single().data
                    "This must be an CustomerState." using (output is CustomerState)
                }
            }
            // signing transaction 1
            val stx = subFlow(signTransactionFlow)
            val customerState = stx.tx.outputs.single().data as CustomerState
            // initiating transaction 2
            subFlow(CustomerIssueOrUpdateFlow(customerState))
    
            return stx
        }
    }
    

    每种方法的优缺点是什么?

    我对选项 1 的担忧是单个流中的两个事务不是原子的。两个事务中的一个可能失败,另一个成功,这将使数据处于不一致的状态。例如:subFlow在上面的响应者中,交易 2 可能会成功,但交易 1 可能会因双花问题而无法通过公证。在那种情况下,第二条链会被不正确地更新。

    使用 vaultTrack会更安全,因为事务 1 会成功,但无法保证事务 2 最终会完成。

    最佳答案

    首先,你说:

    As the data is tracked in two separate states with different participants this would need to be done in two transactions.



    这不一定是真的。具有不同参与者的两个独立状态可以是同一事务的一部分。但是,让我们假设您有理由在此处将它们分开(例如隐私)。

    从 Corda 4 开始,该平台不提供多事务原子性保证。没有内置方法可以确保仅在提交另一个事务时才提交给定事务(但请参阅下面的 P.S.)。

    所以你的选择都不能保证多事务的原子性。我仍然相信选项 1 会更可取,因为您可以获得将调用事务的流程框架的保证。您担心的是,即使第一个事务失败,响应者也会调用创建第二个事务的流。这可以避免使用 waitForLedgerCommit确保在启动创建第二个事务的流程之前提交事务 1:
    class CustomerIssueFlowResponder(val otherPartyFlow: FlowSession) : FlowLogic<SignedTransaction>() {
        @Suspendable
        override fun call(): SignedTransaction {
            val signTransactionFlow = object : SignTransactionFlow(otherPartyFlow) {
                override fun checkTransaction(stx: SignedTransaction) = requireThat {
                    val output = stx.tx.outputs.single().data
                    "This must be an CustomerState." using (output is CustomerState)
                }
            }
            // signing transaction 1
            val stx = subFlow(signTransactionFlow)
            val customerState = stx.tx.outputs.single().data as CustomerState
            // initiating transaction 2 once transaction 1 is committed
            waitForLedgerCommit(stx.id)
            subFlow(CustomerIssueOrUpdateFlow(customerState))
    
            return stx
        }
    }
    

    附言实现多事务原子性的一种可能方法是使用保留,如下所示:
  • 假设我们有两个交易:Tx1,输出 S1,Tx2,输出 S2
  • 作为 Tx1 的一部分,对 S1 进行限制,以便只有当您知道公证人在 Tx2 上的签名时才能使用它,或者在一段时间过去后恢复到其原始状态
  • 作为 Tx2 的一部分,对 S2 进行限制,以便只有当您知道公证人在 Tx1 上的签名时才能使用它,或者在一段时间过去后恢复到其原始状态

  • 然而,我想到的一种攻击是 FinalityFlow 的调用者。因为 Tx1 不会在 Tx1 上分发公证人的签名,允许他们在不放弃 Tx1 的情况下要求 Tx2。如果公证人将其所有签名发布到某个公告板上而不是依赖于 FinalityFlow 的调用者,这将得到解决。分发它们。

    关于corda - 在同一个 Corda 流程中创建多个交易有什么风险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54212354/

    相关文章:

    spring - 使用 Corda 运行 Spring 服务器时出现 Quasar 错误

    java - 出现编译时错误 : The import net. corda.core.testing 无法解析

    java - 如何使用 Corda-Spring-Webserver 实现查询过滤?

    corda - 除了强制信息之外,有没有办法向节点添加更多信息?

    java - com.esotericsoftware.kryo.KryoException : java. lang.UnsupportedOperationException : java. io.StringReader,这是一个可关闭的资源

    corda - 我们如何在 Corda 的发送方和接收方监控 MQ 中传输的交易?

    java - 如何为 Corda RPC 用户创建 Web 身份验证?

    corda - 网络根信任库和 keystore 之间有什么关系?

    java - 如何处理节点共享多个 BNO 的用例

    enterprise - 如何运营 corda 企业