Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added manual settlement rail #20

Merged
merged 32 commits into from
Jun 4, 2019
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a884342
fix warnings and ignore file
Apr 15, 2019
c08fbea
fix warnings and ignore file
Apr 15, 2019
4a0cb83
synced with upstream
Apr 22, 2019
c93d505
synced with upstream
Apr 22, 2019
7d753db
fix error when testing from gradle
Apr 22, 2019
91b9ae2
add UpdatePaymentStatus flow for manual settlement
Apr 23, 2019
a4ad166
fixes and updates and warning fixes
Apr 23, 2019
40ca1de
merged upstream
May 2, 2019
5828095
fix build.gradle
May 2, 2019
2b1593c
got deploying to our artifactory repo
May 2, 2019
0bcdffc
updating to Corda 4
May 7, 2019
7cdf102
working on manual settlement type
May 10, 2019
8debbea
Merge branch 'master' of git://github.com/corda/corda-settler
May 10, 2019
310454c
working on getting UpdateSettlementMethod to work
May 10, 2019
07d4b5a
add dummy contracts so jar attachments work correctly
May 13, 2019
120b607
working on making payments
May 15, 2019
464c2fb
fixes for UpdatePaymentStatus flow
May 16, 2019
3dd615b
add id of canceled obligation for use in notifications
May 21, 2019
169d805
Removed SNAPSHOT from version
May 22, 2019
8e7a5a2
Removed SNAPSHOT from version in build.gradle
May 22, 2019
0615cc5
trying to merge upstream
May 22, 2019
e134158
merged upstream
May 22, 2019
275a708
got working after upstream merge
May 22, 2019
6ae3dff
Merge branch 'master' of git://github.com/corda/corda-settler
May 23, 2019
bfcc691
update build files with upstream versions
May 23, 2019
8df8d01
revert change to .gitignore
May 23, 2019
5e99fda
changes suggested by roger3cev
May 24, 2019
e8b7fd1
added manual tests, fixed checkInvariantProperties to throw exception…
May 29, 2019
5b57694
added manual tests, fixed checkInvariantProperties to throw exception…
May 29, 2019
84c6d9f
disable jar sealing
Jun 3, 2019
436eb42
work lining up send/receive on CreateObligation and OffLedgerSettleOb…
Jun 4, 2019
20e0c61
Merge branch 'master' of git://github.com/corda/corda-settler
Jun 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ lib/dokka.jar
*.iml

## Directory-based project format:
#.idea
.idea/

# if you remove the above rule, at least ignore the following:

Expand Down Expand Up @@ -58,6 +58,10 @@ lib/dokka.jar
/out/
cordapp/out/
cordapp-contracts-states/out/
oracle/out/
ripple/out/
swift/out/
manual/out/

# mpeltonen/sbt-idea plugin
.idea_modules/
Expand Down
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
buildscript {
ext.corda_release_group = 'net.corda'
ext.corda_release_version = '4.1-RC03'
ext.corda_gradle_plugins_version = '4.0.42'
ext.corda_gradle_plugins_version = '4.0.44'
ext.kotlin_version = '1.2.51'
ext.junit_version = '4.12'
ext.quasar_version = '0.7.9'
Expand All @@ -10,6 +10,7 @@ buildscript {
jcenter()
mavenCentral()
mavenLocal()
maven { url "http://ci-artifactory.corda.r3cev.com/artifactory/corda-releases" }
}

dependencies {
Expand Down Expand Up @@ -124,6 +125,8 @@ dependencies {
testCompile project(path: ':cordapp', configuration: 'testOutput')
}

jar.enabled = false

task integrationTest(type: Test, dependsOn: []) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.r3.corda.sdk.token.contracts.types.TokenType
import net.corda.core.contracts.Amount
import net.corda.core.contracts.CommandData
import net.corda.core.contracts.TypeOnlyCommandData
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import java.time.Instant
Expand Down Expand Up @@ -59,5 +60,5 @@ interface ObligationCommands : CommandData {
data class UpdatePayment(val ref: PaymentReference) : ObligationCommands

/** Cancel the obligation - involves exiting the obligation state from the ledger. */
class Cancel : ObligationCommands, TypeOnlyCommandData()
data class Cancel(val id: UniqueIdentifier) : ObligationCommands, TypeOnlyCommandData()
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.r3.corda.finance.obligation.states

import com.r3.corda.finance.obligation.contracts.ObligationContract
import com.r3.corda.finance.obligation.types.Payment
import com.r3.corda.finance.obligation.types.PaymentStatus
import com.r3.corda.finance.obligation.types.SettlementMethod
import com.r3.corda.sdk.token.contracts.types.TokenType
import net.corda.core.contracts.Amount
import net.corda.core.contracts.BelongsToContract
import net.corda.core.contracts.LinearState
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.crypto.toStringShort
Expand Down Expand Up @@ -33,6 +35,8 @@ import java.time.Instant
* 8. Obligations are considered in default if they are not fully paid by the dueDate, if one is specified.
*
*/

@BelongsToContract(ObligationContract::class)
data class Obligation<T : TokenType>(
/** Obligations are always denominated in some token type as we need a reference for FX purposes. */
val faceAmount: Amount<T>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ data class FxRate(val baseCurrency: TokenType, val counterCurrency: TokenType, v
* The obligation could be denominated in GBP but the payment could be made in XRP.
*/
interface OffLedgerPayment<T : AbstractMakeOffLedgerPayment> : SettlementMethod {
/** The Oracle used to determine if payment is made. */
val settlementOracle: Party
/** The Oracle used to determine if payment is made. Use null for manual payment verification */
val settlementOracle: Party?
/** The flow used to initiate the off-ledger payment. */
val paymentFlow: Class<T>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.r3.corda.finance.obligation.client

import net.corda.core.contracts.Contract
import net.corda.core.transactions.LedgerTransaction

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yah, I'm not quite sure how the jar attachment and class loader works here. I was getting errors about not finding the attachment for certain classes. I can try again without this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried again without the DummyContract and got:

[ERROR] 2019-05-24T17:45:40,068Z [Node thread-1] transactions.TransactionBuilder.addMissingAttachment - The transaction currently built is missing an attachment for class: com/r3/corda/finance/obligation/client/flows/MakeOffLedgerPayment.
                        Attempted to find a suitable attachment but could not find any in the storage.
                        Please contact the developer of the CorDapp for further instructions. {actor_id=admin, actor_owning_identity=CN=party2, O=Party2, L=Calgary, C=CA, actor_store_id=NODE_CONFIG, fiber-id=10000011, flow-id=659ad3e0-782d-499d-bf94-bcf82c121f1d, invocation_id=c7976465-392d-4ef9-8186-c114975b11a1, invocation_timestamp=2019-05-24T17:45:37.310Z, origin=admin, session_id=e2027977-e1bc-4464-af6a-05547df67cd8, session_timestamp=2019-05-24T17:44:14.174Z, thread-id=474}
[INFO ] 2019-05-24T17:45:40,068Z [Node thread-1] corda.flow.run - Flow raised an error: com/r3/corda/finance/obligation/client/flows/MakeOffLedgerPayment. Sending it to flow hospital to be triaged. {actor_id=admin, actor_owning_identity=CN=party2, O=Party2, L=Calgary, C=CA, actor_store_id=NODE_CONFIG, fiber-id=10000011, flow-id=659ad3e0-782d-499d-bf94-bcf82c121f1d, invocation_id=c7976465-392d-4ef9-8186-c114975b11a1, invocation_timestamp=2019-05-24T17:45:37.310Z, origin=admin, session_id=e2027977-e1bc-4464-af6a-05547df67cd8, session_timestamp=2019-05-24T17:44:14.174Z, thread-id=474}

and

java.lang.NoClassDefFoundError: com/r3/corda/finance/obligation/client/flows/MakeOffLedgerPayment
        at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_212]
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[?:1.8.0_212]
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_212]
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:468) ~[?:1.8.0_212]
        at java.net.URLClassLoader.access$100(URLClassLoader.java:74) ~[?:1.8.0_212]
        at java.net.URLClassLoader$1.run(URLClassLoader.java:369) ~[?:1.8.0_212]
        at java.net.URLClassLoader$1.run(URLClassLoader.java:363) ~[?:1.8.0_212]
        at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_212]
        at java.net.URLClassLoader.findClass(URLClassLoader.java:362) ~[?:1.8.0_212]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_212]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411) ~[?:1.8.0_212]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_212]
        at java.lang.Class.forName0(Native Method) ~[?:1.8.0_212]
        at java.lang.Class.forName(Class.java:348) ~[?:1.8.0_212]
        at net.corda.serialization.internal.model.TypeIdentifier$Parameterised.getLocalType(TypeIdentifier.kt:209) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.model.TypeIdentifier$Parameterised.getLocalType(TypeIdentifier.kt:218) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.model.ClassCarpentingTypeLoader$load$noCarpentryRequired$1$1.apply(TypeLoader.kt:38) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.model.ClassCarpentingTypeLoader$load$noCarpentryRequired$1$1.apply(TypeLoader.kt:25) ~[corda-serialization-4.1-RC03.jar:?]
        at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) ~[?:1.8.0_212]
        at net.corda.serialization.internal.model.ClassCarpentingTypeLoader$load$noCarpentryRequired$1.invoke(TypeLoader.kt:38) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.model.ClassCarpentingTypeLoader$load$noCarpentryRequired$1.invoke(TypeLoader.kt:25) ~[corda-serialization-4.1-RC03.jar:?]
        at kotlin.sequences.TransformingSequence$iterator$1.next(Sequences.kt:149) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at kotlin.sequences.FilteringSequence$iterator$1.calcNext(Sequences.kt:109) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at kotlin.sequences.FilteringSequence$iterator$1.hasNext(Sequences.kt:133) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at kotlin.collections.MapsKt__MapsKt.putAll(Maps.kt:339) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at kotlin.collections.MapsKt__MapsKt.toMap(Maps.kt:504) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at kotlin.collections.MapsKt__MapsKt.toMap(Maps.kt:498) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at net.corda.serialization.internal.model.ClassCarpentingTypeLoader.load(TypeLoader.kt:45) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DefaultRemoteSerializerFactory.reflect(RemoteSerializerFactory.kt:130) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DefaultRemoteSerializerFactory.access$reflect(RemoteSerializerFactory.kt:48) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DefaultRemoteSerializerFactory$get$1.invoke(RemoteSerializerFactory.kt:72) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DefaultRemoteSerializerFactory$get$1.invoke(RemoteSerializerFactory.kt:48) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DefaultDescriptorBasedSerializerRegistry.getOrBuild(DescriptorBasedSerializerRegistry.kt:28) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DefaultRemoteSerializerFactory.get(RemoteSerializerFactory.kt:67) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.ComposedSerializerFactory.get(SerializerFactory.kt) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DeserializationInput.readObject$serialization(DeserializationInput.kt:172) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DeserializationInput.readObjectOrNull$serialization(DeserializationInput.kt:147) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DescribedTypeReadStrategy.readProperty(ComposableTypePropertySerializer.kt:202) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.ComposableTypePropertySerializer.readProperty(ComposableTypePropertySerializer.kt) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.ComposableObjectReader$readObject$$inlined$ifThrowsAppend$lambda$1.invoke(ObjectSerializer.kt:140) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.ComposableObjectReader$readObject$$inlined$ifThrowsAppend$lambda$1.invoke(ObjectSerializer.kt:122) ~[corda-serialization-4.1-RC03.jar:?]
        at kotlin.sequences.TransformingSequence$iterator$1.next(Sequences.kt:149) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at net.corda.serialization.internal.amqp.ComposableObjectReader.readObject(ObjectSerializer.kt:219) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.ComposableObjectSerializer.readObject(ObjectSerializer.kt:91) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DeserializationInput.readObject$serialization(DeserializationInput.kt:182) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DeserializationInput.readObjectOrNull$serialization(DeserializationInput.kt:147) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DescribedTypeReadStrategy.readProperty(ComposableTypePropertySerializer.kt:202) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.ComposableTypePropertySerializer.readProperty(ComposableTypePropertySerializer.kt) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.ComposableObjectReader$readObject$$inlined$ifThrowsAppend$lambda$1.invoke(ObjectSerializer.kt:140) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.ComposableObjectReader$readObject$$inlined$ifThrowsAppend$lambda$1.invoke(ObjectSerializer.kt:122) ~[corda-serialization-4.1-RC03.jar:?]
        at kotlin.sequences.TransformingSequence$iterator$1.next(Sequences.kt:149) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at net.corda.serialization.internal.amqp.ComposableObjectReader.readObject(ObjectSerializer.kt:219) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.ComposableObjectSerializer.readObject(ObjectSerializer.kt:91) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DeserializationInput.readObject$serialization(DeserializationInput.kt:182) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DeserializationInput.readObjectOrNull$serialization(DeserializationInput.kt:147) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DeserializationInput$deserialize$1.invoke(DeserializationInput.kt:124) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DeserializationInput.des(DeserializationInput.kt:99) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.DeserializationInput.deserialize(DeserializationInput.kt:119) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme.deserialize(AMQPSerializationScheme.kt:225) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.SerializationFactoryImpl$deserialize$1$1.invoke(SerializationScheme.kt:105) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.core.serialization.SerializationFactory.withCurrentContext(SerializationAPI.kt:71) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.serialization.internal.SerializationFactoryImpl$deserialize$1.invoke(SerializationScheme.kt:105) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.serialization.internal.SerializationFactoryImpl$deserialize$1.invoke(SerializationScheme.kt:73) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.core.serialization.SerializationFactory.asCurrent(SerializationAPI.kt:85) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.serialization.internal.SerializationFactoryImpl.deserialize(SerializationScheme.kt:105) ~[corda-serialization-4.1-RC03.jar:?]
        at net.corda.core.internal.TransactionUtilsKt$deserialiseComponentGroup$1.invoke(TransactionUtils.kt:78) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.internal.TransactionUtilsKt$deserialiseComponentGroup$1.invoke(TransactionUtils.kt) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.internal.LazyMappedList.get(InternalUtils.kt:552) ~[corda-core-4.1-RC03.jar:?]
        at java.util.AbstractList$Itr.next(AbstractList.java:358) ~[?:1.8.0_212]
        at java.util.AbstractCollection.toArray(AbstractCollection.java:141) ~[?:1.8.0_212]
        at java.util.ArrayList.addAll(ArrayList.java:581) ~[?:1.8.0_212]
        at kotlin.collections.CollectionsKt___CollectionsKt.plus(_Collections.kt:1970) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at net.corda.core.internal.Verifier.<init>(TransactionVerifierServiceInternal.kt:33) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.LedgerTransaction$internalPrepareVerify$1.invoke(LedgerTransaction.kt:148) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.LedgerTransaction$internalPrepareVerify$1.invoke(LedgerTransaction.kt:45) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.serialization.internal.AttachmentsClassLoaderBuilder$withAttachmentsClassloaderContext$1.invoke(AttachmentsClassLoader.kt:339) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.serialization.SerializationFactory.withCurrentContext(SerializationAPI.kt:71) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.serialization.internal.AttachmentsClassLoaderBuilder.withAttachmentsClassloaderContext(AttachmentsClassLoader.kt:338) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.serialization.internal.AttachmentsClassLoaderBuilder.withAttachmentsClassloaderContext$default(AttachmentsClassLoader.kt:314) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.LedgerTransaction.internalPrepareVerify$core(LedgerTransaction.kt:144) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.LedgerTransaction.verify(LedgerTransaction.kt:134) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.TransactionBuilder.addMissingDependency(TransactionBuilder.kt:186) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.TransactionBuilder.toWireTransactionWithContext$core(TransactionBuilder.kt:166) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.TransactionBuilder.toWireTransactionWithContext$core(TransactionBuilder.kt:169) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.TransactionBuilder.toWireTransactionWithContext$core(TransactionBuilder.kt:169) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.TransactionBuilder.toWireTransactionWithContext$core(TransactionBuilder.kt:169) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.TransactionBuilder.toWireTransactionWithContext$core$default(TransactionBuilder.kt:134) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.TransactionBuilder.toWireTransaction(TransactionBuilder.kt:131) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.transactions.TransactionBuilder.toSignedTransaction(TransactionBuilder.kt:711) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.node.ServiceHub$DefaultImpls.signInitialTransaction(ServiceHub.kt:232) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.core.node.ServiceHub$DefaultImpls.signInitialTransaction(ServiceHub.kt:246) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.node.services.api.ServiceHubInternal$DefaultImpls.signInitialTransaction(ServiceHubInternal.kt) ~[corda-node-4.1-RC03.jar:?]
        at net.corda.node.internal.AbstractNode$ServiceHubInternalImpl.signInitialTransaction(AbstractNode.kt:962) ~[corda-node-4.1-RC03.jar:?]
        at net.corda.core.node.ServiceHub$DefaultImpls.signInitialTransaction(ServiceHub.kt:268) ~[corda-core-4.1-RC03.jar:?]
        at net.corda.node.services.api.ServiceHubInternal$DefaultImpls.signInitialTransaction(ServiceHubInternal.kt) ~[corda-node-4.1-RC03.jar:?]
        at net.corda.node.internal.AbstractNode$ServiceHubInternalImpl.signInitialTransaction(AbstractNode.kt:962) ~[corda-node-4.1-RC03.jar:?]
        at com.r3.corda.finance.obligation.client.flows.UpdateSettlementMethod$Initiator.call(UpdateSettlementMethod.kt:73) ~[?:?]
        at com.r3.corda.finance.obligation.client.flows.UpdateSettlementMethod$Initiator.call(UpdateSettlementMethod.kt:22) ~[?:?]
        at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:269) ~[corda-node-4.1-RC03.jar:?]
        at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:45) ~[corda-node-4.1-RC03.jar:?]
        at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
        at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
        at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_212]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_212]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_212]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[?:1.8.0_212]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_212]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_212]
        at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63) ~[corda-node-4.1-RC03.jar:?]
Caused by: java.lang.ClassNotFoundException: com.r3.corda.finance.obligation.client.flows.MakeOffLedgerPayment
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[?:1.8.0_212]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_212]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_212]
        at net.corda.core.serialization.internal.AttachmentsClassLoader.loadClass(AttachmentsClassLoader.kt:288) ~[corda-core-4.1-RC03.jar:?]
        ... 111 more

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, my bad. I forgot about this... To enable CorDapp dependencies to work, the transaction class loader searches for jars containing the needed classes but it will only search JARs with contract implementations in. Presumably we'll get to fixing this in the next point release. Cheers

class DummyContract : Contract {
override fun verify(tx: LedgerTransaction) = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ object CancelObligation {
val signers = obligation.participants.map { it.owningKey }
val utx = TransactionBuilder(notary = notary).apply {
addInputState(obligationStateAndRef)
addCommand(ObligationCommands.Cancel(), signers)
addCommand(ObligationCommands.Cancel(obligation.linearId), signers)
}

// Get the counterparty and our signing key.
Expand All @@ -69,18 +69,17 @@ object CancelObligation {

// Get the counterparty's signature.
progressTracker.currentStep = COLLECTING
val couterpartyFlow = initiateFlow(counterparty as Party)
val counterpartyFlow = initiateFlow(counterparty as Party)
val stx = subFlow(CollectSignaturesFlow(
partiallySignedTx = ptx,
sessionsToCollectFrom = setOf(couterpartyFlow),
sessionsToCollectFrom = setOf(counterpartyFlow),
myOptionalKeys = listOf(us.owningKey),
progressTracker = COLLECTING.childProgressTracker()
))

progressTracker.currentStep = FINALISING
return subFlow(FinalityFlow(stx, FINALISING.childProgressTracker()))
return subFlow(FinalityFlow(stx, setOf(counterpartyFlow), FINALISING.childProgressTracker()))
}

}

@InitiatedBy(Initiator::class)
Expand All @@ -96,10 +95,7 @@ object CancelObligation {
}
}
val stx = subFlow(flow)
// Suspend this flow until the transaction is committed.
return waitForLedgerCommit(stx.id)
return subFlow(ReceiveFinalityFlow(otherSession, stx.id))
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ object CreateObligation {
override val progressTracker: ProgressTracker = tracker()

@Suspendable
private fun createAnonymousObligation(): Pair<Obligation<T>, PublicKey> {
// TODO: Update to use the new confidential identities constrcutor.
val txKeys = subFlow(SwapIdentitiesFlow(counterparty))
private fun createAnonymousObligation(lenderFlow: FlowSession): Pair<Obligation<T>, PublicKey> {
// TODO: Update to use the new confidential identities constructor.
val txKeys = subFlow(SwapIdentitiesFlow(lenderFlow))
// SwapIdentityFlow should return two keys.
check(txKeys.size == 2) { "Something went wrong when generating confidential identities." }
val anonymousMe = txKeys[ourIdentity] ?: throw FlowException("Couldn't create our conf. identity.")
Expand All @@ -82,8 +82,9 @@ object CreateObligation {
override fun call(): WireTransaction {
// Step 1. Initialisation.
progressTracker.currentStep = INITIALISING
val lenderFlow = initiateFlow(counterparty)
val (obligation, signingKey) = if (anonymous) {
createAnonymousObligation()
createAnonymousObligation(lenderFlow)
} else {
createObligation(us = ourIdentity, them = counterparty)
}
Expand Down Expand Up @@ -113,7 +114,6 @@ object CreateObligation {

// Step 5. Get the counterparty signature.
progressTracker.currentStep = COLLECTING
val lenderFlow = initiateFlow(counterparty)
val stx = subFlow(CollectSignaturesFlow(
partiallySignedTx = ptx,
sessionsToCollectFrom = setOf(lenderFlow),
Expand All @@ -123,8 +123,7 @@ object CreateObligation {

// Step 6. Finalise and return the transaction.
progressTracker.currentStep = FINALISING
// TODO: Update to use teh new FinalityFlow constructor throughout.
val ntx = subFlow(FinalityFlow(stx, FINALISING.childProgressTracker()))
val ntx = subFlow(FinalityFlow(stx, setOf(lenderFlow), FINALISING.childProgressTracker()))
return ntx.tx
}
}
Expand All @@ -142,7 +141,7 @@ object CreateObligation {
}
val stx = subFlow(flow)
// Suspend this flow until the transaction is committed.
return waitForLedgerCommit(stx.id).tx
return subFlow(ReceiveFinalityFlow(otherFlow, stx.id)).tx
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ abstract class MakeOffLedgerPayment<T : TokenType>(
object CHECKING : ProgressTracker.Step("Checking balance.")
object PAYING : ProgressTracker.Step("Making payment.")
object UPDATING : ProgressTracker.Step("Updating obligation with payment details.") {
override fun childProgressTracker() = UpdateObligationWithPayment.tracker()
override fun childProgressTracker() = UpdateObligationWithPayment.Initiator.tracker()
}

fun tracker() = ProgressTracker(SETUP, CHECKING, PAYING, UPDATING)
Expand Down Expand Up @@ -63,7 +63,7 @@ abstract class MakeOffLedgerPayment<T : TokenType>(

// 5. Add payment reference to settlement instructions and update state.
progressTracker.currentStep = UPDATING
return subFlow(UpdateObligationWithPayment(
return subFlow(UpdateObligationWithPayment.Initiator(
linearId = obligation.linearId,
paymentInformation = paymentInformation,
progressTracker = UPDATING.childProgressTracker()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ object NovateObligation {
@StartableByRPC
class Initiator(
val linearId: UniqueIdentifier,
val novationCommand: ObligationCommands.Novate
private val novationCommand: ObligationCommands.Novate
) : FlowLogic<WireTransaction>() {

companion object {
Expand Down Expand Up @@ -126,16 +126,16 @@ object NovateObligation {

// Get the counterparty's signature.
progressTracker.currentStep = COLLECTING
val couterpartyFlow = initiateFlow(counterparty as Party)
val counterpartyFlow = initiateFlow(counterparty as Party)
val stx = subFlow(CollectSignaturesFlow(
partiallySignedTx = ptx,
sessionsToCollectFrom = setOf(couterpartyFlow),
sessionsToCollectFrom = setOf(counterpartyFlow),
myOptionalKeys = listOf(us.owningKey),
progressTracker = COLLECTING.childProgressTracker()
))

progressTracker.currentStep = FINALISING
return subFlow(FinalityFlow(stx, FINALISING.childProgressTracker())).tx
return subFlow(FinalityFlow(stx, setOf(counterpartyFlow), FINALISING.childProgressTracker())).tx
}
}

Expand All @@ -151,8 +151,7 @@ object NovateObligation {
}
}
val stx = subFlow(flow)
// Suspend this flow until the transaction is committed.
return waitForLedgerCommit(stx.id).tx
return subFlow(ReceiveFinalityFlow(otherFlow, stx.id)).tx
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,14 @@ class OffLedgerSettleObligation<T : TokenType>(
progressTracker.currentStep = PAYING
when (settlementMethod) {
is OnLedgerSettlement -> throw IllegalStateException("ObligationContract to be settled on-ledger. Aborting...")
is OffLedgerPayment<*> -> subFlow(getFlowInstance(settlementMethod, obligationStateAndRef, PAYING.childProgressTracker()))
is OffLedgerPayment<*> -> {
val tx = subFlow(getFlowInstance(settlementMethod, obligationStateAndRef, PAYING.childProgressTracker()))
// Checks the payment settled only if settlementOracle != null
// We only supply the linear ID because this flow can be called from the shell on its own.
return if (settlementMethod.settlementOracle == null) tx.tx
else subFlow(SendToSettlementOracle(linearId, SENDING.childProgressTracker())).tx
}
else -> throw IllegalStateException("No settlement instructions added to obligation.")
}

// Checks the payment settled.
// We only supply the linear ID because this flow can be called from the shell on its own.
return subFlow(SendToSettlementOracle(linearId, SENDING.childProgressTracker())).tx
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ class SendToSettlementOracle(
val obligationState = obligationStateAndRef.state.data
val settlementMethod = obligationState.settlementMethod as OffLedgerPayment<*>

val settlementOracle = settlementMethod.settlementOracle
?: throw IllegalArgumentException("Settlement Oracle must not be null")

// Send the Oracle the ObligationContract state.
progressTracker.currentStep = SENDING
val session = initiateFlow(settlementMethod.settlementOracle)
val session = initiateFlow(settlementOracle)
subFlow(SendStateAndRefFlow(session, listOf(obligationStateAndRef)))

// Receive a SignedTransaction from the oracle that exits the obligation, or throw an exception if we timed out.
Expand All @@ -53,7 +56,7 @@ class SendToSettlementOracle(
when (it) {
is SettlementOracleResult.Success -> {
val stx = it.stx
subFlow(FinalityFlow(stx, FINALISING.childProgressTracker()))
subFlow(FinalityFlow(stx, setOf(session), FINALISING.childProgressTracker()))
}
is SettlementOracleResult.Failure -> {
throw IllegalStateException(it.message)
Expand Down
Loading