指向新合同版本的国家是否仍在尝试对旧合同进行反序列化?

时间:2018-11-14 05:30:34

标签: corda

我有一个场景,我将自己的义务从V1升级到V2,并成功指出了正确的V2合同。接下来,我尝试对这些升级的V2状态执行SettleObligation。在CollectSignatureFlow中形成并发送交易后,在我的java.lang.NoSuchMethodError方法中发现了一个isGreaterThan,该方法在合同的verifySettle命令中被调用。

此特定功能最初存在于文件BaseHelper.kt中的包“ com.example.base”上,在V2中,我们将该功能迁移到了另一个文件MathHelper.kt,此举确实因为包是相同的,所以不会导致任何未解决的引用。

想了解:

  1. 合同是否通过文件名而不是程序包名引用功能位置?并且一旦编译contract-v1.jar便无法更改?
  2. 为什么V2州仍尝试对V1合同进行反序列化?这是通过以某种方式沿着链条行走来完成的吗?

下面的堆栈跟踪

[WARN ] 2018-11-13T00:05:12,777Z [Node thread-1] flow.[cd538d42-1715-4ed3-bde6-38eca94ef79f].run - Flow ended due to receiving exception {}
net.corda.core.contracts.TransactionVerificationException$ContractRejection: Contract verification failed: com.example.base.BaseHelperKt.isGreaterThan(Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Z, 
contract: com.example.contracts.ObligationContractV1, transaction: 8B8780A16D330A93A361F747B77C227442BD310C9DAAA561376DED69F580C794
        at net.corda.node.services.statemachine.FlowStateMachineImpl.erroredEnd(FlowStateMachineImpl.kt:497) ~[corda-node-3.2.1847-corda.jar:?]
        at net.corda.node.services.statemachine.FlowStateMachineImpl.confirmNoError(FlowStateMachineImpl.kt:481) ~[corda-node-3.2.1847-corda.jar:?]
        at net.corda.node.services.statemachine.FlowStateMachineImpl.waitForMessage(FlowStateMachineImpl.kt:444) ~[corda-node-3.2.1847-corda.jar:?]
        at net.corda.node.services.statemachine.FlowStateMachineImpl.receiveInternal(FlowStateMachineImpl.kt:376) ~[corda-node-3.2.1847-corda.jar:?]
        at net.corda.node.services.statemachine.FlowStateMachineImpl.receive(FlowStateMachineImpl.kt:229) ~[corda-node-3.2.1847-corda.jar:?]
        at net.corda.node.services.statemachine.FlowSessionImpl.receive(FlowSessionImpl.kt:44) ~[corda-node-3.2.1847-corda.jar:?]
        at net.corda.node.services.statemachine.FlowSessionImpl.receive(FlowSessionImpl.kt:48) ~[corda-node-3.2.1847-corda.jar:?]
        at net.corda.core.flows.CollectSignatureFlow.call(CollectSignaturesFlow.kt:290) ~[corda-core-3.2.1847-corda.jar:?]
        at net.corda.core.flows.CollectSignatureFlow.call(CollectSignaturesFlow.kt:135) ~[corda-core-3.2.1847-corda.jar:?]
        at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:290) ~[corda-core-3.2.1847-corda.jar:?]
        at net.corda.core.flows.CollectSignaturesFlow.call(CollectSignaturesFlow.kt:114) ~[corda-core-3.2.1847-corda.jar:?]
        at net.corda.core.flows.CollectSignaturesFlow.call(CollectSignaturesFlow.kt:64) ~[corda-core-3.2.1847-corda.jar:?]
        at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:290) ~[corda-core-3.2.1847-corda.jar:?]
        at com.example.flows.flows.SettleObligation$Initiator.collectSignature(SettleObligation.kt:178) ~[obligation-1.0.jar:?]
        at com.example.flows.flows.SettleObligation$Initiator.call(SettleObligation.kt:87) ~[obligation-1.0.jar:?]
        at com.example.flows.flows.SettleObligation$Initiator.call(SettleObligation.kt:51) ~[obligation-1.0.jar:?]
        at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:96) [corda-node-3.2.1847-corda.jar:?]
        at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:44) [corda-node-3.2.1847-corda.jar:?]
        at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) [quasar-core-0.7.9-jdk8.jar:0.7.9]
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) [quasar-core-0.7.9-jdk8.jar:0.7.9]
        at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) [quasar-core-0.7.9-jdk8.jar:0.7.9]
        at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) [quasar-core-0.7.9-jdk8.jar:0.7.9]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_181]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_181]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_181]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:1.8.0_181]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_181]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_181]
        at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:62) [corda-node-3.2.1847-corda.jar:?]
Caused by: net.corda.core.CordaRuntimeException: java.lang.NoSuchMethodError: com.example.base.BaseHelperKt.isGreaterThan(Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Z
[INFO ] 2018-11-13T00:05:12,807Z [RxIoScheduler-2] network.PersistentNetworkMapCache.addNode - Previous node was identical to incoming one - doing nothing {}
[INFO ] 2018-11-13T00:05:12,807Z [RxIoScheduler-2] network.PersistentNetworkMapCache.addNode - Done adding node with info: NodeInfo

2 个答案:

答案 0 :(得分:1)

在Kotlin中,每个文件都被编译为JVM级别的类。名为Foobar.kt的文件将成为名为FoobarKt的类。

因此,当将顶级功能从一个文件移动到另一个文件时,文件的名称就会被烘焙到已编译的代码中,并且这样的更改不是二进制的 兼容,即使它与源兼容。

不幸的是,这是所有软件开发中隐藏的复杂性之一-源编译器解析符号范围的方式并不总是与运行时链接程序的方式相同。它会在每种语言和运行时中发生,但是如果有选择的话,JetBrains的人可以通过很长的时间来修复它。抱歉。您必须将函数移回,或提供别名(请查看@JvmName批注)。

答案 1 :(得分:1)

resolveTransactionFlow.kt(沿着链条行走)将依次循环以在验证时获取Tx。在这种情况下,将需要显示所有旧合同代码(作为cordapp),否则您将无法解析该链的出处。

val result = topologicalSort(newTxns)
    result.forEach {
        // For each transaction, verify it and insert it into the database. As we are iterating over them in a
        // depth-first order, we should not encounter any verification failures due to missing data. If we fail
        // half way through, it's no big deal, although it might result in us attempting to re-download data
        // redundantly next time we attempt verification.
        it.verify(serviceHub)
        serviceHub.recordTransactions(StatesToRecord.NONE, listOf(it))
    }