mirror of
https://github.com/corda/corda.git
synced 2025-01-26 06:09:25 +00:00
Enable anonymisation (#1073)
* Enabled confidential identities in: ** IssuerFlow ** Trader demo ** Two party deal flows ** Two party trade flows ** Corda RPC tests ** Cash flows ** Integration testing tutorial ** Node monitor model tests ** CollectSignatureFlow * Relay local node's confidential identities to counterparties when requesting transaction signatures, so counterparties know where the inputs come from. * Require all identities are known in finality flow * Ensure all identities in FxTransactionBuildTutorial are known to each other * Add flow for syncing identities to a number of counterparties * Address PR comments * Disable anonymisation in example code * Revert unnecessary changes remaining from earlier rebases * Corrections after rebase * Remove unneeded identity registration Remove unneeded identity registrations from tests, which sometimes cause duplicated entries in the database * Revert accidental change in examples * Revert unneeded imports * Revert changes to CoreFlowHandlers.kt
This commit is contained in:
parent
330db73c5d
commit
65dcfe4abe
@ -133,8 +133,8 @@ class NodeMonitorModelTest : DriverBasedTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `cash issue and move`() {
|
fun `cash issue and move`() {
|
||||||
val anonymous = false
|
val anonymous = false
|
||||||
rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notaryNode.notaryIdentity).returnValue.getOrThrow()
|
val (_, issueIdentity) = rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notaryNode.notaryIdentity).returnValue.getOrThrow()
|
||||||
rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, bobNode.legalIdentity, anonymous).returnValue.getOrThrow()
|
val (_, paymentIdentity) = rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, bobNode.legalIdentity).returnValue.getOrThrow()
|
||||||
|
|
||||||
var issueSmId: StateMachineRunId? = null
|
var issueSmId: StateMachineRunId? = null
|
||||||
var moveSmId: StateMachineRunId? = null
|
var moveSmId: StateMachineRunId? = null
|
||||||
@ -191,7 +191,7 @@ class NodeMonitorModelTest : DriverBasedTest() {
|
|||||||
require(stx.tx.outputs.size == 1)
|
require(stx.tx.outputs.size == 1)
|
||||||
val signaturePubKeys = stx.sigs.map { it.by }.toSet()
|
val signaturePubKeys = stx.sigs.map { it.by }.toSet()
|
||||||
// Alice and Notary signed
|
// Alice and Notary signed
|
||||||
require(aliceNode.legalIdentity.owningKey.isFulfilledBy(signaturePubKeys))
|
require(issueIdentity!!.owningKey.isFulfilledBy(signaturePubKeys))
|
||||||
require(notaryNode.notaryIdentity.owningKey.isFulfilledBy(signaturePubKeys))
|
require(notaryNode.notaryIdentity.owningKey.isFulfilledBy(signaturePubKeys))
|
||||||
moveTx = stx
|
moveTx = stx
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import net.corda.core.contracts.StateRef
|
|||||||
import net.corda.core.contracts.TransactionState
|
import net.corda.core.contracts.TransactionState
|
||||||
import net.corda.core.crypto.isFulfilledBy
|
import net.corda.core.crypto.isFulfilledBy
|
||||||
import net.corda.core.identity.AbstractParty
|
import net.corda.core.identity.AbstractParty
|
||||||
|
import net.corda.core.crypto.toStringShort
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.ResolveTransactionsFlow
|
import net.corda.core.internal.ResolveTransactionsFlow
|
||||||
import net.corda.core.node.ServiceHub
|
import net.corda.core.node.ServiceHub
|
||||||
@ -126,6 +127,12 @@ open class FinalityFlow(val transactions: Iterable<SignedTransaction>,
|
|||||||
// Calculate who is meant to see the results based on the participants involved.
|
// Calculate who is meant to see the results based on the participants involved.
|
||||||
return extractParticipants(ltx)
|
return extractParticipants(ltx)
|
||||||
.map(this::partyFromAnonymous)
|
.map(this::partyFromAnonymous)
|
||||||
|
.map { participant ->
|
||||||
|
if (participant.wellKnown != null)
|
||||||
|
participant
|
||||||
|
else
|
||||||
|
throw IllegalArgumentException("Could not resolve well known identity of participant ${participant.participant.owningKey.toStringShort()}")
|
||||||
|
}
|
||||||
.toSet()
|
.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,9 @@ import net.corda.core.utilities.ProgressTracker
|
|||||||
import net.corda.core.utilities.unwrap
|
import net.corda.core.utilities.unwrap
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Very basic flow which exchanges transaction key and certificate paths between two parties in a transaction.
|
* Very basic flow which generates new confidential identities for parties in a transaction and exchanges the transaction
|
||||||
* This is intended for use as a subflow of another flow.
|
* key and certificate paths between the parties. This is intended for use as a subflow of another flow which builds a
|
||||||
|
* transaction.
|
||||||
*/
|
*/
|
||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
|
@ -219,6 +219,7 @@ class ContractUpgradeFlowTest {
|
|||||||
val result = a.services.startFlow(CashIssueFlow(Amount(1000, USD), OpaqueBytes.of(1), notary)).resultFuture
|
val result = a.services.startFlow(CashIssueFlow(Amount(1000, USD), OpaqueBytes.of(1), notary)).resultFuture
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
val stx = result.getOrThrow().stx
|
val stx = result.getOrThrow().stx
|
||||||
|
val anonymisedRecipient = result.get().recipient!!
|
||||||
val stateAndRef = stx.tx.outRef<Cash.State>(0)
|
val stateAndRef = stx.tx.outRef<Cash.State>(0)
|
||||||
val baseState = a.database.transaction { a.services.vaultQueryService.queryBy<ContractState>().states.single() }
|
val baseState = a.database.transaction { a.services.vaultQueryService.queryBy<ContractState>().states.single() }
|
||||||
assertTrue(baseState.state.data is Cash.State, "Contract state is old version.")
|
assertTrue(baseState.state.data is Cash.State, "Contract state is old version.")
|
||||||
@ -230,7 +231,7 @@ class ContractUpgradeFlowTest {
|
|||||||
val firstState = a.database.transaction { a.services.vaultQueryService.queryBy<ContractState>().states.single() }
|
val firstState = a.database.transaction { a.services.vaultQueryService.queryBy<ContractState>().states.single() }
|
||||||
assertTrue(firstState.state.data is CashV2.State, "Contract state is upgraded to the new version.")
|
assertTrue(firstState.state.data is CashV2.State, "Contract state is upgraded to the new version.")
|
||||||
assertEquals(Amount(1000000, USD).`issued by`(a.info.legalIdentity.ref(1)), (firstState.state.data as CashV2.State).amount, "Upgraded cash contain the correct amount.")
|
assertEquals(Amount(1000000, USD).`issued by`(a.info.legalIdentity.ref(1)), (firstState.state.data as CashV2.State).amount, "Upgraded cash contain the correct amount.")
|
||||||
assertEquals<Collection<AbstractParty>>(listOf(a.info.legalIdentity), (firstState.state.data as CashV2.State).owners, "Upgraded cash belongs to the right owner.")
|
assertEquals<Collection<AbstractParty>>(listOf(anonymisedRecipient), (firstState.state.data as CashV2.State).owners, "Upgraded cash belongs to the right owner.")
|
||||||
}
|
}
|
||||||
|
|
||||||
class CashV2 : UpgradedContract<Cash.State, CashV2.State> {
|
class CashV2 : UpgradedContract<Cash.State, CashV2.State> {
|
||||||
|
@ -7,12 +7,14 @@ import net.corda.core.transactions.TransactionBuilder
|
|||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.finance.GBP
|
import net.corda.finance.GBP
|
||||||
import net.corda.finance.contracts.asset.Cash
|
import net.corda.finance.contracts.asset.Cash
|
||||||
|
import net.corda.testing.ALICE
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
class FinalityFlowTests {
|
class FinalityFlowTests {
|
||||||
lateinit var mockNet: MockNetwork
|
lateinit var mockNet: MockNetwork
|
||||||
@ -53,4 +55,18 @@ class FinalityFlowTests {
|
|||||||
}
|
}
|
||||||
assertEquals(notarisedTx, transactionSeenByB)
|
assertEquals(notarisedTx, transactionSeenByB)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `reject a transaction with unknown parties`() {
|
||||||
|
val amount = Amount(1000, Issued(nodeA.info.legalIdentity.ref(0), GBP))
|
||||||
|
val fakeIdentity = ALICE // Alice isn't part of this network, so node A won't recognise them
|
||||||
|
val builder = TransactionBuilder(notary)
|
||||||
|
Cash().generateIssue(builder, amount, fakeIdentity, notary)
|
||||||
|
val stx = nodeA.services.signInitialTransaction(builder)
|
||||||
|
val flow = nodeA.services.startFlow(FinalityFlow(stx))
|
||||||
|
mockNet.runNetwork()
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
flow.resultFuture.getOrThrow()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -116,10 +116,10 @@ class CordaRPCOpsImplTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.returnValue.getOrThrow()
|
val anonymisedRecipient = result.returnValue.getOrThrow().recipient!!
|
||||||
val expectedState = Cash.State(Amount(quantity,
|
val expectedState = Cash.State(Amount(quantity,
|
||||||
Issued(aliceNode.info.legalIdentity.ref(ref), GBP)),
|
Issued(aliceNode.info.legalIdentity.ref(ref), GBP)),
|
||||||
recipient)
|
anonymisedRecipient)
|
||||||
|
|
||||||
// Query vault via RPC
|
// Query vault via RPC
|
||||||
val cash = rpc.vaultQueryBy<Cash.State>()
|
val cash = rpc.vaultQueryBy<Cash.State>()
|
||||||
@ -141,7 +141,6 @@ class CordaRPCOpsImplTest {
|
|||||||
vaultTrackCash = rpc.vaultTrackBy<Cash.State>().updates
|
vaultTrackCash = rpc.vaultTrackBy<Cash.State>().updates
|
||||||
}
|
}
|
||||||
|
|
||||||
val anonymous = false
|
|
||||||
val result = rpc.startFlow(::CashIssueFlow,
|
val result = rpc.startFlow(::CashIssueFlow,
|
||||||
100.DOLLARS,
|
100.DOLLARS,
|
||||||
OpaqueBytes(ByteArray(1, { 1 })),
|
OpaqueBytes(ByteArray(1, { 1 })),
|
||||||
@ -150,7 +149,7 @@ class CordaRPCOpsImplTest {
|
|||||||
|
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
|
|
||||||
rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, aliceNode.info.legalIdentity, anonymous)
|
rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, aliceNode.info.legalIdentity)
|
||||||
|
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
|
|
||||||
@ -183,7 +182,7 @@ class CordaRPCOpsImplTest {
|
|||||||
require(stx.tx.inputs.isEmpty())
|
require(stx.tx.inputs.isEmpty())
|
||||||
require(stx.tx.outputs.size == 1)
|
require(stx.tx.outputs.size == 1)
|
||||||
val signaturePubKeys = stx.sigs.map { it.by }.toSet()
|
val signaturePubKeys = stx.sigs.map { it.by }.toSet()
|
||||||
// Only Alice signed
|
// Only Alice signed, as issuer
|
||||||
val aliceKey = aliceNode.info.legalIdentity.owningKey
|
val aliceKey = aliceNode.info.legalIdentity.owningKey
|
||||||
require(signaturePubKeys.size <= aliceKey.keys.size)
|
require(signaturePubKeys.size <= aliceKey.keys.size)
|
||||||
require(aliceKey.isFulfilledBy(signaturePubKeys))
|
require(aliceKey.isFulfilledBy(signaturePubKeys))
|
||||||
@ -194,7 +193,7 @@ class CordaRPCOpsImplTest {
|
|||||||
require(stx.tx.outputs.size == 1)
|
require(stx.tx.outputs.size == 1)
|
||||||
val signaturePubKeys = stx.sigs.map { it.by }.toSet()
|
val signaturePubKeys = stx.sigs.map { it.by }.toSet()
|
||||||
// Alice and Notary signed
|
// Alice and Notary signed
|
||||||
require(aliceNode.info.legalIdentity.owningKey.isFulfilledBy(signaturePubKeys))
|
require(aliceNode.services.keyManagementService.filterMyKeys(signaturePubKeys).toList().isNotEmpty())
|
||||||
require(notaryNode.info.notaryIdentity.owningKey.isFulfilledBy(signaturePubKeys))
|
require(notaryNode.info.notaryIdentity.owningKey.isFulfilledBy(signaturePubKeys))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -337,10 +337,10 @@ class FlowFrameworkTests {
|
|||||||
node1.services.startFlow(CashIssueFlow(
|
node1.services.startFlow(CashIssueFlow(
|
||||||
2000.DOLLARS,
|
2000.DOLLARS,
|
||||||
OpaqueBytes.of(0x01),
|
OpaqueBytes.of(0x01),
|
||||||
notary1.info.notaryIdentity))
|
notary1.info.notaryIdentity)).resultFuture.getOrThrow()
|
||||||
// We pay a couple of times, the notary picking should go round robin
|
// We pay a couple of times, the notary picking should go round robin
|
||||||
for (i in 1..3) {
|
for (i in 1..3) {
|
||||||
val flow = node1.services.startFlow(CashPaymentFlow(500.DOLLARS, node2.info.legalIdentity, anonymous = false))
|
val flow = node1.services.startFlow(CashPaymentFlow(500.DOLLARS, node2.info.legalIdentity))
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
flow.resultFuture.getOrThrow()
|
flow.resultFuture.getOrThrow()
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,8 @@ class BankOfCordaHttpAPITest {
|
|||||||
val bigCorpNodeFuture = startNode(providedName = BIGCORP_LEGAL_NAME)
|
val bigCorpNodeFuture = startNode(providedName = BIGCORP_LEGAL_NAME)
|
||||||
val nodeBankOfCordaFuture = startNode(providedName = BOC.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
|
val nodeBankOfCordaFuture = startNode(providedName = BOC.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
|
||||||
val (nodeBankOfCorda) = listOf(nodeBankOfCordaFuture, bigCorpNodeFuture).map { it.getOrThrow() }
|
val (nodeBankOfCorda) = listOf(nodeBankOfCordaFuture, bigCorpNodeFuture).map { it.getOrThrow() }
|
||||||
val anonymous = false
|
|
||||||
val nodeBankOfCordaApiAddr = startWebserver(nodeBankOfCorda).getOrThrow().listenAddress
|
val nodeBankOfCordaApiAddr = startWebserver(nodeBankOfCorda).getOrThrow().listenAddress
|
||||||
assertTrue(BankOfCordaClientApi(nodeBankOfCordaApiAddr).requestWebIssue(IssueRequestParams(1000, "USD", BIGCORP_LEGAL_NAME, "1", BOC.name, BOC.name, anonymous)))
|
assertTrue(BankOfCordaClientApi(nodeBankOfCordaApiAddr).requestWebIssue(IssueRequestParams(1000, "USD", BIGCORP_LEGAL_NAME, "1", BOC.name, BOC.name)))
|
||||||
}, isDebug = true)
|
}, isDebug = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class BankOfCordaRPCClientTest {
|
|||||||
1000.DOLLARS, BIG_CORP_PARTY_REF,
|
1000.DOLLARS, BIG_CORP_PARTY_REF,
|
||||||
nodeBigCorporation.nodeInfo.legalIdentity,
|
nodeBigCorporation.nodeInfo.legalIdentity,
|
||||||
anonymous,
|
anonymous,
|
||||||
nodeBankOfCorda.nodeInfo.notaryIdentity)
|
nodeBankOfCorda.nodeInfo.notaryIdentity).returnValue.getOrThrow()
|
||||||
|
|
||||||
// Check Bank of Corda Vault Updates
|
// Check Bank of Corda Vault Updates
|
||||||
vaultUpdatesBoc.expectEvents {
|
vaultUpdatesBoc.expectEvents {
|
||||||
|
@ -55,8 +55,7 @@ private class BankOfCordaDriver {
|
|||||||
// The ISSUE_CASH will request some Cash from the ISSUER on behalf of Big Corporation node
|
// The ISSUE_CASH will request some Cash from the ISSUER on behalf of Big Corporation node
|
||||||
val role = options.valueOf(roleArg)!!
|
val role = options.valueOf(roleArg)!!
|
||||||
|
|
||||||
val anonymous = true
|
val requestParams = IssueRequestParams(options.valueOf(quantity), options.valueOf(currency), BIGCORP_LEGAL_NAME, "1", BOC.name, DUMMY_NOTARY.name)
|
||||||
val requestParams = IssueRequestParams(options.valueOf(quantity), options.valueOf(currency), BIGCORP_LEGAL_NAME, "1", BOC.name, DUMMY_NOTARY.name, anonymous)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
when (role) {
|
when (role) {
|
||||||
|
@ -46,9 +46,10 @@ class BankOfCordaClientApi(val hostAndPort: NetworkHostAndPort) {
|
|||||||
?: throw IllegalStateException("Unable to locate notary node in network map cache")
|
?: throw IllegalStateException("Unable to locate notary node in network map cache")
|
||||||
|
|
||||||
val amount = Amount(params.amount, Currency.getInstance(params.currency))
|
val amount = Amount(params.amount, Currency.getInstance(params.currency))
|
||||||
|
val anonymous = true
|
||||||
val issuerBankPartyRef = OpaqueBytes.of(params.issuerBankPartyRef.toByte())
|
val issuerBankPartyRef = OpaqueBytes.of(params.issuerBankPartyRef.toByte())
|
||||||
|
|
||||||
return rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, params.anonymous, notaryNode.notaryIdentity)
|
return rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, anonymous, notaryNode.notaryIdentity)
|
||||||
.returnValue.getOrThrow().stx
|
.returnValue.getOrThrow().stx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,7 @@ class BankOfCordaWebApi(val rpc: CordaRPCOps) {
|
|||||||
data class IssueRequestParams(val amount: Long, val currency: String,
|
data class IssueRequestParams(val amount: Long, val currency: String,
|
||||||
val issueToPartyName: X500Name, val issuerBankPartyRef: String,
|
val issueToPartyName: X500Name, val issuerBankPartyRef: String,
|
||||||
val issuerBankName: X500Name,
|
val issuerBankName: X500Name,
|
||||||
val notaryName: X500Name,
|
val notaryName: X500Name)
|
||||||
val anonymous: Boolean)
|
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val logger = loggerFor<BankOfCordaWebApi>()
|
val logger = loggerFor<BankOfCordaWebApi>()
|
||||||
@ -51,12 +50,13 @@ class BankOfCordaWebApi(val rpc: CordaRPCOps) {
|
|||||||
?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate $notaryParty in network map service").build()
|
?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate $notaryParty in network map service").build()
|
||||||
|
|
||||||
val amount = Amount(params.amount, Currency.getInstance(params.currency))
|
val amount = Amount(params.amount, Currency.getInstance(params.currency))
|
||||||
|
val anonymous = true
|
||||||
val issuerBankPartyRef = OpaqueBytes.of(params.issuerBankPartyRef.toByte())
|
val issuerBankPartyRef = OpaqueBytes.of(params.issuerBankPartyRef.toByte())
|
||||||
|
|
||||||
// invoke client side of Issuer Flow: IssuanceRequester
|
// invoke client side of Issuer Flow: IssuanceRequester
|
||||||
// The line below blocks and waits for the future to resolve.
|
// The line below blocks and waits for the future to resolve.
|
||||||
return try {
|
return try {
|
||||||
rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, params.anonymous, notaryNode.notaryIdentity).returnValue.getOrThrow()
|
rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, anonymous, notaryNode.notaryIdentity).returnValue.getOrThrow()
|
||||||
logger.info("Issue and payment request completed successfully: $params")
|
logger.info("Issue and payment request completed successfully: $params")
|
||||||
Response.status(Response.Status.CREATED).build()
|
Response.status(Response.Status.CREATED).build()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -56,7 +56,6 @@ class TraderDemoTest : NodeBasedTest() {
|
|||||||
val expectedBCash = clientB.cashCount + 1
|
val expectedBCash = clientB.cashCount + 1
|
||||||
val expectedPaper = listOf(clientA.commercialPaperCount + 1, clientB.commercialPaperCount)
|
val expectedPaper = listOf(clientA.commercialPaperCount + 1, clientB.commercialPaperCount)
|
||||||
|
|
||||||
// TODO: Enable anonymisation
|
|
||||||
clientBank.runIssuer(amount = 100.DOLLARS, buyerName = nodeA.info.legalIdentity.name, sellerName = nodeB.info.legalIdentity.name)
|
clientBank.runIssuer(amount = 100.DOLLARS, buyerName = nodeA.info.legalIdentity.name, sellerName = nodeB.info.legalIdentity.name)
|
||||||
clientB.runSeller(buyerName = nodeA.info.legalIdentity.name, amount = 5.DOLLARS)
|
clientB.runSeller(buyerName = nodeA.info.legalIdentity.name, amount = 5.DOLLARS)
|
||||||
|
|
||||||
|
@ -51,12 +51,11 @@ class TraderDemoClientApi(val rpc: CordaRPCOps) {
|
|||||||
val notaryNode = rpc.nodeIdentityFromParty(notaryLegalIdentity)
|
val notaryNode = rpc.nodeIdentityFromParty(notaryLegalIdentity)
|
||||||
?: throw IllegalStateException("Unable to locate notary node in network map cache")
|
?: throw IllegalStateException("Unable to locate notary node in network map cache")
|
||||||
val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random())
|
val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random())
|
||||||
val anonymous = false
|
|
||||||
rpc.startFlow(::CashIssueFlow, amount, OpaqueBytes.of(1), notaryNode.notaryIdentity).returnValue.getOrThrow()
|
rpc.startFlow(::CashIssueFlow, amount, OpaqueBytes.of(1), notaryNode.notaryIdentity).returnValue.getOrThrow()
|
||||||
// Pay random amounts of currency up to the requested amount
|
// Pay random amounts of currency up to the requested amount
|
||||||
amounts.forEach { pennies ->
|
amounts.forEach { pennies ->
|
||||||
// TODO This can't be done in parallel, perhaps due to soft-locking issues?
|
// TODO This can't be done in parallel, perhaps due to soft-locking issues?
|
||||||
rpc.startFlow(::CashPaymentFlow, amount.copy(quantity = pennies), buyer, anonymous).returnValue.getOrThrow()
|
rpc.startFlow(::CashPaymentFlow, amount.copy(quantity = pennies), buyer).returnValue.getOrThrow()
|
||||||
}
|
}
|
||||||
println("Cash issued to buyer")
|
println("Cash issued to buyer")
|
||||||
|
|
||||||
|
@ -149,8 +149,7 @@ class NewTransaction : Fragment() {
|
|||||||
dialogPane = root
|
dialogPane = root
|
||||||
initOwner(window)
|
initOwner(window)
|
||||||
setResultConverter {
|
setResultConverter {
|
||||||
// TODO: Enable confidential identities
|
val anonymous = true
|
||||||
val anonymous = false
|
|
||||||
val defaultRef = OpaqueBytes.of(1)
|
val defaultRef = OpaqueBytes.of(1)
|
||||||
val issueRef = if (issueRef.value != null) OpaqueBytes.of(issueRef.value) else defaultRef
|
val issueRef = if (issueRef.value != null) OpaqueBytes.of(issueRef.value) else defaultRef
|
||||||
when (it) {
|
when (it) {
|
||||||
|
@ -123,14 +123,13 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
|
|||||||
|
|
||||||
generate = { (nodeVaults), parallelism ->
|
generate = { (nodeVaults), parallelism ->
|
||||||
val nodeMap = simpleNodes.associateBy { it.info.legalIdentity }
|
val nodeMap = simpleNodes.associateBy { it.info.legalIdentity }
|
||||||
val anonymous = true
|
|
||||||
Generator.pickN(parallelism, simpleNodes).flatMap { nodes ->
|
Generator.pickN(parallelism, simpleNodes).flatMap { nodes ->
|
||||||
Generator.sequence(
|
Generator.sequence(
|
||||||
nodes.map { node ->
|
nodes.map { node ->
|
||||||
val quantities = nodeVaults[node.info.legalIdentity] ?: mapOf()
|
val quantities = nodeVaults[node.info.legalIdentity] ?: mapOf()
|
||||||
val possibleRecipients = nodeMap.keys.toList()
|
val possibleRecipients = nodeMap.keys.toList()
|
||||||
val moves = quantities.map {
|
val moves = quantities.map {
|
||||||
it.value.toDouble() / 1000 to generateMove(it.value, USD, node.info.legalIdentity, possibleRecipients, anonymous)
|
it.value.toDouble() / 1000 to generateMove(it.value, USD, node.info.legalIdentity, possibleRecipients)
|
||||||
}
|
}
|
||||||
val exits = quantities.mapNotNull {
|
val exits = quantities.mapNotNull {
|
||||||
if (it.key == node.info.legalIdentity) {
|
if (it.key == node.info.legalIdentity) {
|
||||||
@ -140,7 +139,7 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val command = Generator.frequency(
|
val command = Generator.frequency(
|
||||||
listOf(1.0 to generateIssue(10000, USD, notary.info.notaryIdentity, possibleRecipients, anonymous)) + moves + exits
|
listOf(1.0 to generateIssue(10000, USD, notary.info.notaryIdentity, possibleRecipients)) + moves + exits
|
||||||
)
|
)
|
||||||
command.map { CrossCashCommand(it, nodeMap[node.info.legalIdentity]!!) }
|
command.map { CrossCashCommand(it, nodeMap[node.info.legalIdentity]!!) }
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,13 @@ fun generateIssue(
|
|||||||
max: Long,
|
max: Long,
|
||||||
currency: Currency,
|
currency: Currency,
|
||||||
notary: Party,
|
notary: Party,
|
||||||
possibleRecipients: List<Party>,
|
possibleRecipients: List<Party>
|
||||||
anonymous: Boolean
|
|
||||||
): Generator<IssueAndPaymentRequest> {
|
): Generator<IssueAndPaymentRequest> {
|
||||||
return generateAmount(1, max, Generator.pure(currency)).combine(
|
return generateAmount(1, 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 ->
|
||||||
IssueAndPaymentRequest(amount, ref, recipient, notary, anonymous)
|
IssueAndPaymentRequest(amount, ref, recipient, notary, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,13 +30,12 @@ fun generateMove(
|
|||||||
max: Long,
|
max: Long,
|
||||||
currency: Currency,
|
currency: Currency,
|
||||||
issuer: Party,
|
issuer: Party,
|
||||||
possibleRecipients: List<Party>,
|
possibleRecipients: List<Party>
|
||||||
anonymous: Boolean
|
|
||||||
): Generator<PaymentRequest> {
|
): Generator<PaymentRequest> {
|
||||||
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 ->
|
||||||
PaymentRequest(amount.withoutIssuer(), recipient, anonymous, setOf(issuer))
|
PaymentRequest(amount.withoutIssuer(), recipient, true, setOf(issuer))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ val selfIssueTest = LoadTest<SelfIssueCommand, SelfIssueState>(
|
|||||||
|
|
||||||
generate = { _, parallelism ->
|
generate = { _, parallelism ->
|
||||||
val generateIssue = Generator.pickOne(simpleNodes).flatMap { node ->
|
val generateIssue = Generator.pickOne(simpleNodes).flatMap { node ->
|
||||||
generateIssue(1000, USD, notary.info.notaryIdentity, listOf(node.info.legalIdentity), anonymous = true).map {
|
generateIssue(1000, USD, notary.info.notaryIdentity, listOf(node.info.legalIdentity)).map {
|
||||||
SelfIssueCommand(it, node)
|
SelfIssueCommand(it, node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user