From 17a1e149fa4785a2167becfe915b534de31e9030 Mon Sep 17 00:00:00 2001 From: Jose Coll Date: Thu, 24 Aug 2023 16:56:11 +0100 Subject: [PATCH] Update notary demo to ensure txn signed by all before recording. --- samples/notary-demo/build.gradle | 36 +++++++++++++++++++ .../net/corda/notarydemo/client/Notarise.kt | 4 +-- .../notarydemo/flows/DummyIssueAndMove.kt | 23 ++++++++++-- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/samples/notary-demo/build.gradle b/samples/notary-demo/build.gradle index 6f87b55b35..e448345573 100644 --- a/samples/notary-demo/build.gradle +++ b/samples/notary-demo/build.gradle @@ -58,6 +58,15 @@ task deployNodesSingle(type: Cordform, dependsOn: ['jar', nodeTask, webTask]) { } rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] } + node { + name "O=Bob Plc,L=Rome,C=IT" + p2pPort 10005 + rpcSettings { + address "localhost:10006" + adminAddress "localhost:10007" + } + rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] + } node { name "O=Notary Node,L=Zurich,C=CH" p2pPort 10009 @@ -90,6 +99,15 @@ task deployNodesCustom(type: Cordform, dependsOn: ['jar', nodeTask, webTask]) { } rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] } + node { + name "O=Bob Plc,L=Rome,C=IT" + p2pPort 10005 + rpcSettings { + address "localhost:10006" + adminAddress "localhost:10007" + } + rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] + } node { name "O=Notary Node,L=Zurich,C=CH" p2pPort 10009 @@ -124,6 +142,15 @@ task deployNodesRaft(type: Cordform, dependsOn: ['jar', nodeTask, webTask]) { } rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] } + node { + name "O=Bob Plc,L=Rome,C=IT" + p2pPort 10005 + rpcSettings { + address "localhost:10006" + adminAddress "localhost:10007" + } + rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] + } node { name "O=Notary Service 0,L=Zurich,C=CH" p2pPort 10009 @@ -193,6 +220,15 @@ task deployNodesBFT(type: Cordform, dependsOn: ['jar', nodeTask, webTask]) { } rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] } + node { + name "O=Bob Plc,L=Rome,C=IT" + p2pPort 10005 + rpcSettings { + address "localhost:10006" + adminAddress "localhost:10007" + } + rpcUsers = [[user: "demou", password: "demop", permissions: ["ALL"]]] + } node { name "O=Notary Service 0,L=Zurich,C=CH" p2pPort 10009 diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/client/Notarise.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/client/Notarise.kt index 0f1648752d..711f7042fd 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/client/Notarise.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/client/Notarise.kt @@ -2,10 +2,8 @@ package net.corda.notarydemo.client import net.corda.client.rpc.CordaRPCClient import net.corda.core.crypto.CompositeKey -import net.corda.core.crypto.Crypto import net.corda.core.crypto.toStringShort import net.corda.core.identity.CordaX500Name -import net.corda.core.identity.Party import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.startFlow import net.corda.core.transactions.SignedTransaction @@ -32,7 +30,7 @@ private class NotaryDemoClientApi(val rpc: CordaRPCOps) { /** A dummy identity. */ private val BOB_NAME = CordaX500Name("Bob Plc", "Rome", "IT") - private val counterparty = Party(BOB_NAME, Crypto.generateKeyPair(Crypto.DEFAULT_SIGNATURE_SCHEME).public) + private val counterparty = rpc.wellKnownPartyFromX500Name(BOB_NAME) ?: throw IllegalArgumentException("Couldn't find Bob Plc party") /** Makes calls to the node rpc to start transaction notarisation. */ fun notarise(count: Int) { diff --git a/samples/notary-demo/workflows/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt b/samples/notary-demo/workflows/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt index dfa7c02ae0..a73a805e31 100644 --- a/samples/notary-demo/workflows/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt +++ b/samples/notary-demo/workflows/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt @@ -2,15 +2,22 @@ package net.corda.notarydemo.flows import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.ContractState +import net.corda.core.flows.FinalityFlow import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession +import net.corda.core.flows.InitiatedBy +import net.corda.core.flows.InitiatingFlow +import net.corda.core.flows.ReceiveFinalityFlow import net.corda.core.flows.StartableByRPC import net.corda.core.identity.Party +import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder import net.corda.notarydemo.contracts.DO_NOTHING_PROGRAM_ID import net.corda.notarydemo.contracts.DummyCommand import net.corda.notarydemo.contracts.DummyState +@InitiatingFlow @StartableByRPC class DummyIssueAndMove(private val notary: Party, private val counterpartyNode: Party, private val discriminator: Int) : FlowLogic() { @Suspendable @@ -22,12 +29,22 @@ class DummyIssueAndMove(private val notary: Party, private val counterpartyNode: addCommand(DummyCommand(), listOf(ourIdentity.owningKey)) }) serviceHub.recordTransactions(issueTx) - // Move ownership of the asset to the counterparty - // We don't check signatures because we know that the notary's signature is missing - return serviceHub.signInitialTransaction(TransactionBuilder(notary).apply { + + val stx = serviceHub.signInitialTransaction(TransactionBuilder(notary).apply { addInputState(issueTx.tx.outRef(0)) addOutputState(state.copy(participants = listOf(counterpartyNode)), DO_NOTHING_PROGRAM_ID) addCommand(DummyCommand(), listOf(ourIdentity.owningKey)) }) + + return subFlow(FinalityFlow(stx, initiateFlow(counterpartyNode))) } } + +@InitiatedBy(DummyIssueAndMove::class) +class DummyIssueAndMoveResponder(private val otherSide: FlowSession) : FlowLogic() { + @Suspendable + override fun call() { + // As a non-participant to the transaction we need to record all states + subFlow(ReceiveFinalityFlow(otherSide, statesToRecord = StatesToRecord.ALL_VISIBLE)) + } +} \ No newline at end of file