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:
Ross Nicoll 2017-09-11 14:29:37 +01:00 committed by GitHub
parent 330db73c5d
commit 65dcfe4abe
18 changed files with 55 additions and 38 deletions

View File

@ -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
} }

View File

@ -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()
} }

View File

@ -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

View File

@ -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> {

View File

@ -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()
}
}
} }

View File

@ -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))
} }
) )

View File

@ -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()
} }

View File

@ -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)
} }
} }

View File

@ -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 {

View File

@ -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) {

View File

@ -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
} }
} }

View File

@ -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) {

View File

@ -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)

View File

@ -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")

View File

@ -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) {

View File

@ -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]!!) }
} }

View File

@ -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))
} }
} }

View File

@ -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)
} }
} }