Change CashIssueFlow to always issue to ourselves

Change CashIssueFlow to always issue to ourselves, and require the cash is then moved in a separate payment
operation. This more closely models actual operation inside banks, and is a step towards making all move-like
operations go through a uniform verification process.
This commit is contained in:
Ross Nicoll
2017-08-11 17:02:39 +01:00
parent 89476904fc
commit b76d036843
29 changed files with 111 additions and 168 deletions

View File

@ -1,8 +1,6 @@
package net.corda.docs
import net.corda.contracts.asset.Cash
import net.corda.core.concurrent.CordaFuture
import net.corda.finance.DOLLARS
import net.corda.core.internal.concurrent.transpose
import net.corda.core.messaging.startFlow
import net.corda.core.messaging.vaultTrackBy
@ -10,6 +8,7 @@ import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS
import net.corda.flows.CashIssueFlow
import net.corda.flows.CashPaymentFlow
import net.corda.node.services.startFlowPermission
@ -17,13 +16,7 @@ import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.nodeapi.User
import net.corda.testing.*
import net.corda.testing.driver.driver
import net.corda.testing.expect
import net.corda.testing.expectEvents
import net.corda.testing.parallel
import net.corda.testing.sequence
import org.junit.Test
import java.util.*
import kotlin.concurrent.thread
import kotlin.test.assertEquals
class IntegrationTestingTutorial {
@ -32,7 +25,8 @@ class IntegrationTestingTutorial {
// START 1
driver {
val aliceUser = User("aliceUser", "testPassword1", permissions = setOf(
startFlowPermission<CashIssueFlow>()
startFlowPermission<CashIssueFlow>(),
startFlowPermission<CashPaymentFlow>()
))
val bobUser = User("bobUser", "testPassword2", permissions = setOf(
startFlowPermission<CashPaymentFlow>()
@ -62,20 +56,21 @@ class IntegrationTestingTutorial {
// START 4
val issueRef = OpaqueBytes.of(0)
val futures = Stack<CordaFuture<*>>()
(1..10).map { i ->
thread {
futures.push(aliceProxy.startFlow(::CashIssueFlow,
i.DOLLARS,
bob.nodeInfo.legalIdentity,
alice.nodeInfo.legalIdentity,
issueRef,
notary.nodeInfo.notaryIdentity,
true
).returnValue)
}
}.forEach(Thread::join) // Ensure the stack of futures is populated.
futures.forEach { it.getOrThrow() }
aliceProxy.startFlow(::CashIssueFlow,
i.DOLLARS,
issueRef,
notary.nodeInfo.notaryIdentity
).returnValue
}.transpose().getOrThrow()
// We wait for all of the issuances to run before we start making payments
(1..10).map { i ->
aliceProxy.startFlow(::CashPaymentFlow,
i.DOLLARS,
bob.nodeInfo.legalIdentity,
true
).returnValue
}.transpose().getOrThrow()
bobVaultUpdates.expectEvents {
parallel(

View File

@ -128,7 +128,7 @@ fun generateTransactions(proxy: CordaRPCOps) {
proxy.startFlow(::CashPaymentFlow, Amount(quantity, USD), me)
} else {
val quantity = Math.abs(random.nextLong() % 1000)
proxy.startFlow(::CashIssueFlow, Amount(quantity, USD), me, me, issueRef, notary, true)
proxy.startFlow(::CashIssueFlow, Amount(quantity, USD), issueRef, notary)
ownedQuantity += quantity
}
}

View File

@ -133,8 +133,7 @@ object TopupIssuerFlow {
// invoke Cash subflow to issue Asset
progressTracker.currentStep = ISSUING
val issuer = serviceHub.myInfo.legalIdentity
val issueRecipient = serviceHub.myInfo.legalIdentity
val issueCashFlow = CashIssueFlow(amount, issueRecipient, issuer, issuerPartyRef, notaryParty, anonymous = false)
val issueCashFlow = CashIssueFlow(amount, issuerPartyRef, notaryParty)
val issueTx = subFlow(issueCashFlow)
// NOTE: issueCashFlow performs a Broadcast (which stores a local copy of the txn to the ledger)
// short-circuit when issuing to self

View File

@ -65,11 +65,8 @@ class CustomVaultQueryTest {
private fun issueCashForCurrency(amountToIssue: Amount<Currency>) {
// Use NodeA as issuer and create some dollars
val flowHandle1 = nodeA.services.startFlow(CashIssueFlow(amountToIssue,
nodeA.info.legalIdentity,
nodeA.info.legalIdentity,
OpaqueBytes.of(0x01),
notaryNode.info.notaryIdentity,
anonymous = false))
notaryNode.info.notaryIdentity))
// Wait for the flow to stop and print
flowHandle1.resultFuture.getOrThrow()
}

View File

@ -45,22 +45,16 @@ class FxTransactionBuildTutorialTest {
fun `Run ForeignExchangeFlow to completion`() {
// Use NodeA as issuer and create some dollars
val flowHandle1 = nodeA.services.startFlow(CashIssueFlow(DOLLARS(1000),
nodeA.info.legalIdentity,
nodeA.info.legalIdentity,
OpaqueBytes.of(0x01),
notaryNode.info.notaryIdentity,
false))
notaryNode.info.notaryIdentity))
// Wait for the flow to stop and print
flowHandle1.resultFuture.getOrThrow()
printBalances()
// Using NodeB as Issuer create some pounds.
val flowHandle2 = nodeB.services.startFlow(CashIssueFlow(POUNDS(1000),
nodeB.info.legalIdentity,
nodeB.info.legalIdentity,
OpaqueBytes.of(0x01),
notaryNode.info.notaryIdentity,
false))
notaryNode.info.notaryIdentity))
// Wait for flow to come to an end and print
flowHandle2.resultFuture.getOrThrow()
printBalances()