Remove CashFlow

Remove the CashFlow flow, replacing it with CashFlowCommand which can be used for the use-cases
with instructions passed around as an object.
This commit is contained in:
Ross Nicoll 2017-02-03 14:07:45 +00:00
parent 288d709668
commit 98c30f6432
14 changed files with 147 additions and 152 deletions

View File

@ -10,6 +10,9 @@ import net.corda.core.random63BitValue
import net.corda.core.serialization.OpaqueBytes import net.corda.core.serialization.OpaqueBytes
import net.corda.flows.CashIssueFlow import net.corda.flows.CashIssueFlow
import net.corda.flows.CashPaymentFlow import net.corda.flows.CashPaymentFlow
import net.corda.node.driver.DriverBasedTest
import net.corda.node.driver.NodeHandle
import net.corda.node.driver.driver
import net.corda.node.internal.Node import net.corda.node.internal.Node
import net.corda.node.services.User import net.corda.node.services.User
import net.corda.node.services.config.configureTestSSL import net.corda.node.services.config.configureTestSSL

View File

@ -19,7 +19,9 @@ import net.corda.core.node.services.StateMachineTransactionMapping
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.serialization.OpaqueBytes import net.corda.core.serialization.OpaqueBytes
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.flows.CashFlow import net.corda.flows.CashExitFlow
import net.corda.flows.CashIssueFlow
import net.corda.flows.CashPaymentFlow
import net.corda.node.driver.DriverBasedTest import net.corda.node.driver.DriverBasedTest
import net.corda.node.driver.driver import net.corda.node.driver.driver
import net.corda.node.services.User import net.corda.node.services.User
@ -48,7 +50,11 @@ class NodeMonitorModelTest : DriverBasedTest() {
lateinit var newNode: (String) -> NodeInfo lateinit var newNode: (String) -> NodeInfo
override fun setup() = driver { override fun setup() = driver {
val cashUser = User("user1", "test", permissions = setOf(startFlowPermission<CashFlow>())) val cashUser = User("user1", "test", permissions = setOf(
startFlowPermission<CashIssueFlow>(),
startFlowPermission<CashPaymentFlow>(),
startFlowPermission<CashExitFlow>())
)
val aliceNodeFuture = startNode("Alice", rpcUsers = listOf(cashUser)) val aliceNodeFuture = startNode("Alice", rpcUsers = listOf(cashUser))
val notaryNodeFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) val notaryNodeFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
@ -93,12 +99,12 @@ class NodeMonitorModelTest : DriverBasedTest() {
@Test @Test
fun `cash issue works end to end`() { fun `cash issue works end to end`() {
rpc.startFlow(::CashFlow, CashFlow.Command.IssueCash( rpc.startFlow(::CashIssueFlow,
amount = Amount(100, USD), Amount(100, USD),
issueRef = OpaqueBytes(ByteArray(1, { 1 })), OpaqueBytes(ByteArray(1, { 1 })),
recipient = aliceNode.legalIdentity, aliceNode.legalIdentity,
notary = notaryNode.notaryIdentity notaryNode.notaryIdentity
)) )
vaultUpdates.expectEvents(isStrict = false) { vaultUpdates.expectEvents(isStrict = false) {
sequence( sequence(
@ -118,17 +124,17 @@ class NodeMonitorModelTest : DriverBasedTest() {
@Test @Test
fun `cash issue and move`() { fun `cash issue and move`() {
rpc.startFlow(::CashFlow, CashFlow.Command.IssueCash( rpc.startFlow(::CashIssueFlow,
amount = Amount(100, USD), Amount(100, USD),
issueRef = OpaqueBytes(ByteArray(1, { 1 })), OpaqueBytes(ByteArray(1, { 1 })),
recipient = aliceNode.legalIdentity, aliceNode.legalIdentity,
notary = notaryNode.notaryIdentity notaryNode.notaryIdentity
)).returnValue.getOrThrow() ).returnValue.getOrThrow()
rpc.startFlow(::CashFlow, CashFlow.Command.PayCash( rpc.startFlow(::CashPaymentFlow,
amount = Amount(100, Issued(PartyAndReference(aliceNode.legalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)), Amount(100, Issued(PartyAndReference(aliceNode.legalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)),
recipient = aliceNode.legalIdentity aliceNode.legalIdentity
)) )
var issueSmId: StateMachineRunId? = null var issueSmId: StateMachineRunId? = null
var moveSmId: StateMachineRunId? = null var moveSmId: StateMachineRunId? = null

View File

@ -5,7 +5,7 @@ import net.corda.core.contracts.*
import net.corda.core.crypto.Party import net.corda.core.crypto.Party
import net.corda.core.serialization.OpaqueBytes import net.corda.core.serialization.OpaqueBytes
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.flows.CashFlow import net.corda.flows.CashFlowCommand
import java.util.* import java.util.*
/** /**
@ -64,7 +64,7 @@ class EventGenerator(
val issueCashGenerator = val issueCashGenerator =
amountGenerator.combine(partyGenerator, issueRefGenerator) { amount, to, issueRef -> amountGenerator.combine(partyGenerator, issueRefGenerator) { amount, to, issueRef ->
CashFlow.Command.IssueCash( CashFlowCommand.IssueCash(
amount, amount,
issueRef, issueRef,
to, to,
@ -76,7 +76,7 @@ class EventGenerator(
amountIssuedGenerator.combine( amountIssuedGenerator.combine(
partyGenerator partyGenerator
) { amountIssued, recipient -> ) { amountIssued, recipient ->
CashFlow.Command.PayCash( CashFlowCommand.PayCash(
amount = amountIssued, amount = amountIssued,
recipient = recipient recipient = recipient
) )
@ -84,7 +84,7 @@ class EventGenerator(
val exitCashGenerator = val exitCashGenerator =
amountIssuedGenerator.map { amountIssuedGenerator.map {
CashFlow.Command.ExitCash( CashFlowCommand.ExitCash(
it.withoutIssuer(), it.withoutIssuer(),
it.token.issuer.reference it.token.issuer.reference
) )

View File

@ -8,7 +8,7 @@ import net.corda.core.crypto.SecureHash
import net.corda.core.getOrThrow import net.corda.core.getOrThrow
import net.corda.core.serialization.OpaqueBytes import net.corda.core.serialization.OpaqueBytes
import net.corda.core.utilities.Emoji import net.corda.core.utilities.Emoji
import net.corda.flows.CashFlow import net.corda.flows.CashIssueFlow
import net.corda.flows.ContractUpgradeFlow import net.corda.flows.ContractUpgradeFlow
import net.corda.flows.FinalityFlow import net.corda.flows.FinalityFlow
import net.corda.node.utilities.databaseTransaction import net.corda.node.utilities.databaseTransaction
@ -90,7 +90,7 @@ class ContractUpgradeFlowTest {
@Test @Test
fun `upgrade Cash to v2`() { fun `upgrade Cash to v2`() {
// Create some cash. // Create some cash.
val result = a.services.startFlow(CashFlow(CashFlow.Command.IssueCash(Amount(1000, USD), OpaqueBytes.of(1), a.info.legalIdentity, notary))).resultFuture val result = a.services.startFlow(CashIssueFlow(Amount(1000, USD), OpaqueBytes.of(1), a.info.legalIdentity, notary)).resultFuture
mockNet.runNetwork() mockNet.runNetwork()
val stateAndRef = result.getOrThrow().tx.outRef<Cash.State>(0) val stateAndRef = result.getOrThrow().tx.outRef<Cash.State>(0)
// Starts contract upgrade flow. // Starts contract upgrade flow.

View File

@ -10,7 +10,8 @@ import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.serialization.OpaqueBytes import net.corda.core.serialization.OpaqueBytes
import net.corda.core.toFuture import net.corda.core.toFuture
import net.corda.flows.CashFlow import net.corda.flows.CashIssueFlow
import net.corda.flows.CashPaymentFlow
import net.corda.node.driver.driver import net.corda.node.driver.driver
import net.corda.node.services.User import net.corda.node.services.User
import net.corda.node.services.startFlowPermission import net.corda.node.services.startFlowPermission
@ -28,7 +29,10 @@ class IntegrationTestingTutorial {
fun `alice bob cash exchange example`() { fun `alice bob cash exchange example`() {
// START 1 // START 1
driver { driver {
val testUser = User("testUser", "testPassword", permissions = setOf(startFlowPermission<CashFlow>())) val testUser = User("testUser", "testPassword", permissions = setOf(
startFlowPermission<CashIssueFlow>(),
startFlowPermission<CashPaymentFlow>()
))
val (alice, bob, notary) = Futures.allAsList( val (alice, bob, notary) = Futures.allAsList(
startNode("Alice", rpcUsers = listOf(testUser)), startNode("Alice", rpcUsers = listOf(testUser)),
startNode("Bob", rpcUsers = listOf(testUser)), startNode("Bob", rpcUsers = listOf(testUser)),
@ -56,12 +60,12 @@ class IntegrationTestingTutorial {
val issueRef = OpaqueBytes.of(0) val issueRef = OpaqueBytes.of(0)
for (i in 1 .. 10) { for (i in 1 .. 10) {
thread { thread {
aliceProxy.startFlow(::CashFlow, CashFlow.Command.IssueCash( aliceProxy.startFlow(::CashIssueFlow,
amount = i.DOLLARS, i.DOLLARS,
issueRef = issueRef, issueRef,
recipient = bob.nodeInfo.legalIdentity, bob.nodeInfo.legalIdentity,
notary = notary.nodeInfo.notaryIdentity notary.nodeInfo.notaryIdentity
)) )
} }
} }
@ -82,10 +86,10 @@ class IntegrationTestingTutorial {
// START 5 // START 5
for (i in 1 .. 10) { for (i in 1 .. 10) {
val flowHandle = bobProxy.startFlow(::CashFlow, CashFlow.Command.PayCash( val flowHandle = bobProxy.startFlow(::CashPaymentFlow,
amount = i.DOLLARS.issuedBy(alice.nodeInfo.legalIdentity.ref(issueRef)), i.DOLLARS.issuedBy(alice.nodeInfo.legalIdentity.ref(issueRef)),
recipient = alice.nodeInfo.legalIdentity alice.nodeInfo.legalIdentity
)) )
flowHandle.returnValue.getOrThrow() flowHandle.returnValue.getOrThrow()
} }

View File

@ -9,6 +9,9 @@ Milestone 9
* API: * API:
* Pseudonymous ``AnonymousParty`` class added as a superclass of ``Party``. * Pseudonymous ``AnonymousParty`` class added as a superclass of ``Party``.
* Split ``CashFlow`` into individual ``CashIssueFlow``, ``CashPaymentFlow`` and ``CashExitFlow`` flows, so that fine
grained permissions can be applied. Added ``CashFlowCommand`` for use-cases where cash flow triggers need to be
captured in an object that can be passed around.
Milestone 8 Milestone 8
----------- -----------

View File

@ -1,67 +0,0 @@
package net.corda.flows
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.Amount
import net.corda.core.contracts.Issued
import net.corda.core.crypto.Party
import net.corda.core.flows.FlowLogic
import net.corda.core.serialization.OpaqueBytes
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.ProgressTracker
import java.util.*
/**
* Initiates a flow that produces an Issue/Move or Exit Cash transaction.
*
* @param command Indicates what Cash transaction to create with what parameters.
*/
class CashFlow(val command: CashFlow.Command, override val progressTracker: ProgressTracker) : FlowLogic<SignedTransaction>() {
constructor(command: CashFlow.Command) : this(command, tracker())
companion object {
object ISSUING : ProgressTracker.Step("Issuing cash")
object PAYING : ProgressTracker.Step("Paying cash")
object EXITING : ProgressTracker.Step("Exiting cash")
fun tracker() = ProgressTracker(ISSUING, PAYING, EXITING)
}
@Suspendable
@Throws(CashException::class)
override fun call(): SignedTransaction {
return when (command) {
is CashFlow.Command.IssueCash -> subFlow(CashIssueFlow(command.amount, command.issueRef, command.recipient, command.notary))
is CashFlow.Command.PayCash -> subFlow(CashPaymentFlow(command.amount, command.recipient))
is CashFlow.Command.ExitCash -> subFlow(CashExitFlow(command.amount, command.issueRef))
}
}
/**
* A command to initiate the Cash flow with.
*/
sealed class Command {
/**
* A command to initiate the Cash flow with.
*/
class IssueCash(val amount: Amount<Currency>,
val issueRef: OpaqueBytes,
val recipient: Party,
val notary: Party) : CashFlow.Command()
/**
* Pay cash to someone else.
*
* @param amount the amount of currency to issue on to the ledger.
* @param recipient the party to issue the cash to.
*/
class PayCash(val amount: Amount<Issued<Currency>>, val recipient: Party) : CashFlow.Command()
/**
* Exit cash from the ledger.
*
* @param amount the amount of currency to exit from the ledger.
* @param issueRef the reference previously specified on the issuance.
*/
class ExitCash(val amount: Amount<Currency>, val issueRef: OpaqueBytes) : CashFlow.Command()
}
}

View File

@ -0,0 +1,48 @@
package net.corda.flows
import net.corda.core.contracts.Amount
import net.corda.core.contracts.Issued
import net.corda.core.crypto.Party
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.FlowHandle
import net.corda.core.messaging.startFlow
import net.corda.core.serialization.OpaqueBytes
import net.corda.core.transactions.SignedTransaction
import java.util.*
/**
* A command to initiate the Cash flow with.
*/
sealed class CashFlowCommand {
abstract fun startFlow(proxy: CordaRPCOps): FlowHandle<SignedTransaction>
/**
* A command to initiate the Cash flow with.
*/
class IssueCash(val amount: Amount<Currency>,
val issueRef: OpaqueBytes,
val recipient: Party,
val notary: Party) : CashFlowCommand() {
override fun startFlow(proxy: CordaRPCOps) = proxy.startFlow(::CashIssueFlow, amount, issueRef, recipient, notary)
}
/**
* Pay cash to someone else.
*
* @param amount the amount of currency to issue on to the ledger.
* @param recipient the party to issue the cash to.
*/
class PayCash(val amount: Amount<Issued<Currency>>, val recipient: Party) : CashFlowCommand() {
override fun startFlow(proxy: CordaRPCOps) = proxy.startFlow(::CashPaymentFlow, amount, recipient)
}
/**
* Exit cash from the ledger.
*
* @param amount the amount of currency to exit from the ledger.
* @param issueRef the reference previously specified on the issuance.
*/
class ExitCash(val amount: Amount<Currency>, val issueRef: OpaqueBytes) : CashFlowCommand() {
override fun startFlow(proxy: CordaRPCOps) = proxy.startFlow(::CashExitFlow, amount, issueRef)
}
}

View File

@ -81,9 +81,6 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
val PUBLIC_IDENTITY_FILE_NAME = "identity-public" val PUBLIC_IDENTITY_FILE_NAME = "identity-public"
val defaultFlowWhiteList: Map<Class<out FlowLogic<*>>, Set<Class<*>>> = mapOf( val defaultFlowWhiteList: Map<Class<out FlowLogic<*>>, Set<Class<*>>> = mapOf(
CashFlow::class.java to setOf(CashFlow.Command.IssueCash::class.java,
CashFlow.Command.PayCash::class.java,
CashFlow.Command.ExitCash::class.java),
CashExitFlow::class.java to setOf(Amount::class.java, PartyAndReference::class.java), CashExitFlow::class.java to setOf(Amount::class.java, PartyAndReference::class.java),
CashIssueFlow::class.java to setOf(Amount::class.java, OpaqueBytes::class.java, Party::class.java), CashIssueFlow::class.java to setOf(Amount::class.java, OpaqueBytes::class.java, Party::class.java),
CashPaymentFlow::class.java to setOf(Amount::class.java, Party::class.java), CashPaymentFlow::class.java to setOf(Amount::class.java, Party::class.java),

View File

@ -21,7 +21,9 @@ import net.corda.explorer.model.CordaViewModel
import net.corda.explorer.model.SettingsModel import net.corda.explorer.model.SettingsModel
import net.corda.explorer.views.* import net.corda.explorer.views.*
import net.corda.explorer.views.cordapps.cash.CashViewer import net.corda.explorer.views.cordapps.cash.CashViewer
import net.corda.flows.CashFlow import net.corda.flows.CashExitFlow
import net.corda.flows.CashIssueFlow
import net.corda.flows.CashPaymentFlow
import net.corda.flows.IssuerFlow.IssuanceRequester import net.corda.flows.IssuerFlow.IssuanceRequester
import net.corda.node.driver.PortAllocation import net.corda.node.driver.PortAllocation
import net.corda.node.driver.driver import net.corda.node.driver.driver
@ -107,8 +109,15 @@ class Main : App(MainView::class) {
fun main(args: Array<String>) { fun main(args: Array<String>) {
val portAllocation = PortAllocation.Incremental(20000) val portAllocation = PortAllocation.Incremental(20000)
driver(portAllocation = portAllocation) { driver(portAllocation = portAllocation) {
val user = User("user1", "test", permissions = setOf(startFlowPermission<CashFlow>())) val user = User("user1", "test", permissions = setOf(
val manager = User("manager", "test", permissions = setOf(startFlowPermission<CashFlow>(), startFlowPermission<IssuanceRequester>())) startFlowPermission<CashPaymentFlow>()
))
val manager = User("manager", "test", permissions = setOf(
startFlowPermission<CashIssueFlow>(),
startFlowPermission<CashPaymentFlow>(),
startFlowPermission<CashExitFlow>(),
startFlowPermission<IssuanceRequester>())
)
// TODO : Supported flow should be exposed somehow from the node instead of set of ServiceInfo. // TODO : Supported flow should be exposed somehow from the node instead of set of ServiceInfo.
val notary = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)), val notary = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)),
customOverrides = mapOf("nearestCity" to "Zurich")) customOverrides = mapOf("nearestCity" to "Zurich"))
@ -178,34 +187,26 @@ fun main(args: Array<String>) {
// Party pay requests // Party pay requests
listOf(aliceRPC, bobRPC).forEach { listOf(aliceRPC, bobRPC).forEach {
eventGenerator.clientCommandGenerator.map { command -> eventGenerator.clientCommandGenerator.map { command ->
it.startFlow(::CashFlow, command) command.startFlow(it)
Unit Unit
}.generate(SplittableRandom()) }.generate(SplittableRandom())
} }
// Exit requests // Exit requests
issuerGBPEventGenerator.bankOfCordaExitGenerator.map { command -> issuerGBPEventGenerator.bankOfCordaExitGenerator.map { command ->
issuerRPCGBP.startFlow(::CashFlow, command) command.startFlow(issuerRPCGBP)
Unit Unit
}.generate(SplittableRandom()) }.generate(SplittableRandom())
issuerUSDEventGenerator.bankOfCordaExitGenerator.map { command -> issuerUSDEventGenerator.bankOfCordaExitGenerator.map { command ->
issuerRPCUSD.startFlow(::CashFlow, command) command.startFlow(issuerRPCUSD)
Unit Unit
}.generate(SplittableRandom()) }.generate(SplittableRandom())
// Issuer requests // Issuer requests
issuerGBPEventGenerator.bankOfCordaIssueGenerator.map { command -> issuerGBPEventGenerator.bankOfCordaIssueGenerator.map { command ->
issuerRPCGBP.startFlow(::IssuanceRequester, command.startFlow(issuerRPCGBP)
command.amount,
command.recipient,
command.issueRef,
issuerNodeGBP.nodeInfo.legalIdentity)
Unit Unit
}.generate(SplittableRandom()) }.generate(SplittableRandom())
issuerUSDEventGenerator.bankOfCordaIssueGenerator.map { command -> issuerUSDEventGenerator.bankOfCordaIssueGenerator.map { command ->
issuerRPCUSD.startFlow(::IssuanceRequester, command.startFlow(issuerRPCUSD)
command.amount,
command.recipient,
command.issueRef,
issuerNodeUSD.nodeInfo.legalIdentity)
Unit Unit
}.generate(SplittableRandom()) }.generate(SplittableRandom())
} }

View File

@ -28,7 +28,7 @@ import net.corda.explorer.model.ReportingCurrencyModel
import net.corda.explorer.views.bigDecimalFormatter import net.corda.explorer.views.bigDecimalFormatter
import net.corda.explorer.views.byteFormatter import net.corda.explorer.views.byteFormatter
import net.corda.explorer.views.stringConverter import net.corda.explorer.views.stringConverter
import net.corda.flows.CashFlow import net.corda.flows.CashFlowCommand
import net.corda.flows.IssuerFlow.IssuanceRequester import net.corda.flows.IssuerFlow.IssuanceRequester
import org.controlsfx.dialog.ExceptionDialog import org.controlsfx.dialog.ExceptionDialog
import tornadofx.Fragment import tornadofx.Fragment
@ -87,7 +87,7 @@ class NewTransaction : Fragment() {
} }
dialog.show() dialog.show()
runAsync { runAsync {
val handle = if (it is CashFlow.Command.IssueCash) { val handle = if (it is CashFlowCommand.IssueCash) {
myIdentity.value?.let { myIdentity -> myIdentity.value?.let { myIdentity ->
rpcProxy.value!!.startFlow(::IssuanceRequester, rpcProxy.value!!.startFlow(::IssuanceRequester,
it.amount, it.amount,
@ -96,7 +96,7 @@ class NewTransaction : Fragment() {
myIdentity.legalIdentity) myIdentity.legalIdentity)
} }
} else { } else {
rpcProxy.value!!.startFlow(::CashFlow, it) it.startFlow(rpcProxy.value!!)
} }
val response = try { val response = try {
handle?.returnValue?.getOrThrow() handle?.returnValue?.getOrThrow()
@ -110,9 +110,9 @@ class NewTransaction : Fragment() {
Alert.AlertType.ERROR to response.message Alert.AlertType.ERROR to response.message
} else { } else {
val type = when (command) { val type = when (command) {
is CashFlow.Command.IssueCash -> "Cash Issued" is CashFlowCommand.IssueCash -> "Cash Issued"
is CashFlow.Command.ExitCash -> "Cash Exited" is CashFlowCommand.ExitCash -> "Cash Exited"
is CashFlow.Command.PayCash -> "Cash Paid" is CashFlowCommand.PayCash -> "Cash Paid"
} }
Alert.AlertType.INFORMATION to "$type \nTransaction ID : ${(response as SignedTransaction).id}" Alert.AlertType.INFORMATION to "$type \nTransaction ID : ${(response as SignedTransaction).id}"
} }
@ -127,7 +127,7 @@ class NewTransaction : Fragment() {
} }
} }
private fun dialog(window: Window) = Dialog<CashFlow.Command>().apply { private fun dialog(window: Window) = Dialog<CashFlowCommand>().apply {
dialogPane = root dialogPane = root
initOwner(window) initOwner(window)
setResultConverter { setResultConverter {
@ -136,10 +136,10 @@ class NewTransaction : Fragment() {
when (it) { when (it) {
executeButton -> when (transactionTypeCB.value) { executeButton -> when (transactionTypeCB.value) {
CashTransaction.Issue -> { CashTransaction.Issue -> {
CashFlow.Command.IssueCash(Amount(amount.value, currencyChoiceBox.value), issueRef, partyBChoiceBox.value.legalIdentity, notaries.first().notaryIdentity) CashFlowCommand.IssueCash(Amount(amount.value, currencyChoiceBox.value), issueRef, partyBChoiceBox.value.legalIdentity, notaries.first().notaryIdentity)
} }
CashTransaction.Pay -> CashFlow.Command.PayCash(Amount(amount.value, Issued(PartyAndReference(issuerChoiceBox.value, issueRef), currencyChoiceBox.value)), partyBChoiceBox.value.legalIdentity) CashTransaction.Pay -> CashFlowCommand.PayCash(Amount(amount.value, Issued(PartyAndReference(issuerChoiceBox.value, issueRef), currencyChoiceBox.value)), partyBChoiceBox.value.legalIdentity)
CashTransaction.Exit -> CashFlow.Command.ExitCash(Amount(amount.value, currencyChoiceBox.value), issueRef) CashTransaction.Exit -> CashFlowCommand.ExitCash(Amount(amount.value, currencyChoiceBox.value), issueRef)
else -> null else -> null
} }
else -> null else -> null

View File

@ -14,7 +14,7 @@ import net.corda.core.messaging.startFlow
import net.corda.core.serialization.OpaqueBytes import net.corda.core.serialization.OpaqueBytes
import net.corda.core.toFuture import net.corda.core.toFuture
import net.corda.flows.CashException import net.corda.flows.CashException
import net.corda.flows.CashFlow import net.corda.flows.CashFlowCommand
import net.corda.loadtest.LoadTest import net.corda.loadtest.LoadTest
import net.corda.loadtest.NodeHandle import net.corda.loadtest.NodeHandle
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -29,18 +29,18 @@ private val log = LoggerFactory.getLogger("CrossCash")
*/ */
data class CrossCashCommand( data class CrossCashCommand(
val command: CashFlow.Command, val command: CashFlowCommand,
val node: NodeHandle val node: NodeHandle
) { ) {
override fun toString(): String { override fun toString(): String {
return when (command) { return when (command) {
is CashFlow.Command.IssueCash -> { is CashFlowCommand.IssueCash -> {
"ISSUE ${node.info.legalIdentity} -> ${command.recipient} : ${command.amount}" "ISSUE ${node.info.legalIdentity} -> ${command.recipient} : ${command.amount}"
} }
is CashFlow.Command.PayCash -> { is CashFlowCommand.PayCash -> {
"MOVE ${node.info.legalIdentity} -> ${command.recipient} : ${command.amount}" "MOVE ${node.info.legalIdentity} -> ${command.recipient} : ${command.amount}"
} }
is CashFlow.Command.ExitCash -> { is CashFlowCommand.ExitCash -> {
"EXIT ${node.info.legalIdentity} : ${command.amount}" "EXIT ${node.info.legalIdentity} : ${command.amount}"
} }
} }
@ -146,7 +146,7 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
interpret = { state, command -> interpret = { state, command ->
when (command.command) { when (command.command) {
is CashFlow.Command.IssueCash -> { is CashFlowCommand.IssueCash -> {
val newDiffQueues = state.copyQueues() val newDiffQueues = state.copyQueues()
val originators = newDiffQueues.getOrPut(command.command.recipient, { HashMap() }) val originators = newDiffQueues.getOrPut(command.command.recipient, { HashMap() })
val issuer = command.node.info.legalIdentity val issuer = command.node.info.legalIdentity
@ -156,7 +156,7 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
queue.add(Pair(issuer, quantity)) queue.add(Pair(issuer, quantity))
CrossCashState(state.nodeVaults, newDiffQueues) CrossCashState(state.nodeVaults, newDiffQueues)
} }
is CashFlow.Command.PayCash -> { is CashFlowCommand.PayCash -> {
val newNodeVaults = state.copyVaults() val newNodeVaults = state.copyVaults()
val newDiffQueues = state.copyQueues() val newDiffQueues = state.copyQueues()
val recipientOriginators = newDiffQueues.getOrPut(command.command.recipient, { HashMap() }) val recipientOriginators = newDiffQueues.getOrPut(command.command.recipient, { HashMap() })
@ -183,7 +183,7 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
recipientQueue.add(Pair(issuer, quantity)) recipientQueue.add(Pair(issuer, quantity))
CrossCashState(newNodeVaults, newDiffQueues) CrossCashState(newNodeVaults, newDiffQueues)
} }
is CashFlow.Command.ExitCash -> { is CashFlowCommand.ExitCash -> {
val newNodeVaults = state.copyVaults() val newNodeVaults = state.copyVaults()
val issuer = command.node.info.legalIdentity val issuer = command.node.info.legalIdentity
val quantity = command.command.amount.quantity val quantity = command.command.amount.quantity
@ -209,7 +209,7 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
execute = { command -> execute = { command ->
try { try {
val result = command.node.connection.proxy.startFlow(::CashFlow, command.command).returnValue.getOrThrow() val result = command.command.startFlow(command.node.connection.proxy).returnValue.getOrThrow()
log.info("Success: $result") log.info("Success: $result")
} catch (e: FlowException) { } catch (e: FlowException) {
log.error("Failure", e) log.error("Failure", e)

View File

@ -8,7 +8,7 @@ import net.corda.core.contracts.PartyAndReference
import net.corda.core.crypto.AnonymousParty import net.corda.core.crypto.AnonymousParty
import net.corda.core.crypto.Party import net.corda.core.crypto.Party
import net.corda.core.serialization.OpaqueBytes import net.corda.core.serialization.OpaqueBytes
import net.corda.flows.CashFlow import net.corda.flows.CashFlowCommand
import java.util.* import java.util.*
fun generateIssue( fun generateIssue(
@ -16,12 +16,12 @@ fun generateIssue(
currency: Currency, currency: Currency,
notary: Party, notary: Party,
possibleRecipients: List<Party> possibleRecipients: List<Party>
): Generator<CashFlow.Command.IssueCash> { ): Generator<CashFlowCommand.IssueCash> {
return generateAmount(0, max, Generator.pure(currency)).combine( return generateAmount(0, max, Generator.pure(currency)).combine(
Generator.pure(OpaqueBytes.of(0)), Generator.pure(OpaqueBytes.of(0)),
Generator.pickOne(possibleRecipients) Generator.pickOne(possibleRecipients)
) { amount, ref, recipient -> ) { amount, ref, recipient ->
CashFlow.Command.IssueCash(amount, ref, recipient, notary) CashFlowCommand.IssueCash(amount, ref, recipient, notary)
} }
} }
@ -30,19 +30,19 @@ fun generateMove(
currency: Currency, currency: Currency,
issuer: AnonymousParty, issuer: AnonymousParty,
possibleRecipients: List<Party> possibleRecipients: List<Party>
): Generator<CashFlow.Command.PayCash> { ): Generator<CashFlowCommand.PayCash> {
return generateAmount(1, max, Generator.pure(Issued(PartyAndReference(issuer, OpaqueBytes.of(0)), currency))).combine( return generateAmount(1, max, Generator.pure(Issued(PartyAndReference(issuer, OpaqueBytes.of(0)), currency))).combine(
Generator.pickOne(possibleRecipients) Generator.pickOne(possibleRecipients)
) { amount, recipient -> ) { amount, recipient ->
CashFlow.Command.PayCash(amount, recipient) CashFlowCommand.PayCash(amount, recipient)
} }
} }
fun generateExit( fun generateExit(
max: Long, max: Long,
currency: Currency currency: Currency
): Generator<CashFlow.Command.ExitCash> { ): Generator<CashFlowCommand.ExitCash> {
return generateAmount(1, max, Generator.pure(currency)).map { amount -> return generateAmount(1, max, Generator.pure(currency)).map { amount ->
CashFlow.Command.ExitCash(amount, OpaqueBytes.of(0)) CashFlowCommand.ExitCash(amount, OpaqueBytes.of(0))
} }
} }

View File

@ -13,7 +13,7 @@ import net.corda.core.getOrThrow
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.toFuture import net.corda.core.toFuture
import net.corda.flows.CashException import net.corda.flows.CashException
import net.corda.flows.CashFlow import net.corda.flows.CashFlowCommand
import net.corda.loadtest.LoadTest import net.corda.loadtest.LoadTest
import net.corda.loadtest.NodeHandle import net.corda.loadtest.NodeHandle
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -23,7 +23,7 @@ private val log = LoggerFactory.getLogger("SelfIssue")
// DOCS START 1 // DOCS START 1
data class SelfIssueCommand( data class SelfIssueCommand(
val command: CashFlow.Command.IssueCash, val command: CashFlowCommand.IssueCash,
val node: NodeHandle val node: NodeHandle
) )
@ -64,7 +64,7 @@ val selfIssueTest = LoadTest<SelfIssueCommand, SelfIssueState>(
execute = { command -> execute = { command ->
try { try {
val result = command.node.connection.proxy.startFlow(::CashFlow, command.command).returnValue.getOrThrow() val result = command.command.startFlow(command.node.connection.proxy).returnValue.getOrThrow()
log.info("Success: $result") log.info("Success: $result")
} catch (e: FlowException) { } catch (e: FlowException) {
log.error("Failure", e) log.error("Failure", e)