mirror of
https://github.com/corda/corda.git
synced 2025-02-25 19:11:45 +00:00
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:
parent
288d709668
commit
98c30f6432
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
@ -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.
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
-----------
|
-----------
|
||||||
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
48
finance/src/main/kotlin/net/corda/flows/CashFlowCommand.kt
Normal file
48
finance/src/main/kotlin/net/corda/flows/CashFlowCommand.kt
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
@ -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),
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user