mirror of
https://github.com/corda/corda.git
synced 2025-06-17 06:38:21 +00:00
Enable anonymisation in two party deal/trade flows
This commit is contained in:
@ -11,6 +11,7 @@ import net.corda.core.flows.StateMachineRunId
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.internal.FlowStateMachine
|
||||
import net.corda.core.internal.concurrent.map
|
||||
import net.corda.core.internal.rootCause
|
||||
@ -20,6 +21,7 @@ import net.corda.core.messaging.StateMachineTransactionMapping
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.node.services.Vault
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.toFuture
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
@ -145,19 +147,18 @@ class TwoPartyTradeFlowTests {
|
||||
val aliceNode = mockNet.createPartyNode(notaryNode.network.myAddress, ALICE.name)
|
||||
val bobNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOB.name)
|
||||
val bankNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOC.name)
|
||||
val cashIssuer = bankNode.info.legalIdentity.ref(1)
|
||||
val cpIssuer = bankNode.info.legalIdentity.ref(1, 2, 3)
|
||||
val issuer = bankNode.info.legalIdentity.ref(1)
|
||||
|
||||
aliceNode.disableDBCloseOnStop()
|
||||
bobNode.disableDBCloseOnStop()
|
||||
|
||||
val cashStates = bobNode.database.transaction {
|
||||
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, notaryNode.info.notaryIdentity, 3, 3,
|
||||
issuedBy = cashIssuer)
|
||||
issuedBy = issuer)
|
||||
}
|
||||
|
||||
val alicesFakePaper = aliceNode.database.transaction {
|
||||
fillUpForSeller(false, cpIssuer, aliceNode.info.legalIdentity,
|
||||
fillUpForSeller(false, issuer, aliceNode.info.legalIdentity,
|
||||
1200.DOLLARS `issued by` bankNode.info.legalIdentity.ref(0), null, notaryNode.info.notaryIdentity).second
|
||||
}
|
||||
|
||||
@ -199,8 +200,13 @@ class TwoPartyTradeFlowTests {
|
||||
val aliceNode = mockNet.createPartyNode(notaryNode.network.myAddress, ALICE.name)
|
||||
var bobNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOB.name)
|
||||
val bankNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOC.name)
|
||||
val cashIssuer = bankNode.info.legalIdentity.ref(1)
|
||||
val cpIssuer = bankNode.info.legalIdentity.ref(1, 2, 3)
|
||||
val issuer = bankNode.info.legalIdentity.ref(1, 2, 3)
|
||||
|
||||
// Let the nodes know about each other - normally the network map would handle this
|
||||
val allNodes = listOf(notaryNode, aliceNode, bobNode, bankNode)
|
||||
allNodes.forEach { node ->
|
||||
allNodes.map { it.services.myInfo.legalIdentityAndCert }.forEach { identity -> node.services.identityService.registerIdentity(identity) }
|
||||
}
|
||||
|
||||
aliceNode.services.identityService.verifyAndRegisterIdentity(bobNode.info.legalIdentityAndCert)
|
||||
bobNode.services.identityService.verifyAndRegisterIdentity(aliceNode.info.legalIdentityAndCert)
|
||||
@ -214,10 +220,10 @@ class TwoPartyTradeFlowTests {
|
||||
|
||||
bobNode.database.transaction {
|
||||
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, outputNotary = notaryNode.info.notaryIdentity,
|
||||
issuedBy = cashIssuer)
|
||||
issuedBy = issuer)
|
||||
}
|
||||
val alicesFakePaper = aliceNode.database.transaction {
|
||||
fillUpForSeller(false, cpIssuer, aliceNode.info.legalIdentity,
|
||||
fillUpForSeller(false, issuer, aliceNode.info.legalIdentity,
|
||||
1200.DOLLARS `issued by` bankNode.info.legalIdentity.ref(0), null, notaryNode.info.notaryIdentity).second
|
||||
}
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
|
||||
@ -253,6 +259,9 @@ class TwoPartyTradeFlowTests {
|
||||
// She will wait around until Bob comes back.
|
||||
assertThat(aliceNode.pumpReceive()).isNotNull()
|
||||
|
||||
// FIXME: Knowledge of confidential identities is lost on node shutdown, so Bob's node now refuses to sign the
|
||||
// transaction because it has no idea who the parties are.
|
||||
|
||||
// ... bring the node back up ... the act of constructing the SMM will re-register the message handlers
|
||||
// that Bob was waiting on before the reboot occurred.
|
||||
bobNode = mockNet.createNode(networkMapAddress, bobAddr.id, object : MockNetwork.Factory<MockNetwork.MockNode> {
|
||||
@ -437,7 +446,6 @@ class TwoPartyTradeFlowTests {
|
||||
}
|
||||
|
||||
ledger(aliceNode.services, initialiseSerialization = false) {
|
||||
|
||||
// Insert a prospectus type attachment into the commercial paper transaction.
|
||||
val stream = ByteArrayOutputStream()
|
||||
JarOutputStream(stream).use {
|
||||
@ -529,13 +537,11 @@ class TwoPartyTradeFlowTests {
|
||||
private fun runBuyerAndSeller(notaryNode: MockNetwork.MockNode,
|
||||
sellerNode: MockNetwork.MockNode,
|
||||
buyerNode: MockNetwork.MockNode,
|
||||
assetToSell: StateAndRef<OwnableState>): RunResult {
|
||||
val anonymousSeller = sellerNode.services.let { serviceHub ->
|
||||
serviceHub.keyManagementService.freshKeyAndCert(serviceHub.myInfo.legalIdentityAndCert, false)
|
||||
}.party.anonymise()
|
||||
val buyerFlows: Observable<BuyerAcceptor> = buyerNode.registerInitiatedFlow(BuyerAcceptor::class.java)
|
||||
assetToSell: StateAndRef<OwnableState>,
|
||||
anonymous: Boolean = true): RunResult {
|
||||
val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.registerInitiatedFlow(BuyerAcceptor::class.java)
|
||||
val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine }
|
||||
val seller = SellerInitiator(buyerNode.info.legalIdentity, notaryNode.info, assetToSell, 1000.DOLLARS, anonymousSeller)
|
||||
val seller = SellerInitiator(buyerNode.info.legalIdentity, notaryNode.info, assetToSell, 1000.DOLLARS, anonymous)
|
||||
val sellerResult = sellerNode.services.startFlow(seller).resultFuture
|
||||
return RunResult(firstBuyerFiber, sellerResult, seller.stateMachine.id)
|
||||
}
|
||||
@ -545,10 +551,15 @@ class TwoPartyTradeFlowTests {
|
||||
val notary: NodeInfo,
|
||||
val assetToSell: StateAndRef<OwnableState>,
|
||||
val price: Amount<Currency>,
|
||||
val me: AnonymousParty) : FlowLogic<SignedTransaction>() {
|
||||
val anonymous: Boolean) : FlowLogic<SignedTransaction>() {
|
||||
@Suspendable
|
||||
override fun call(): SignedTransaction {
|
||||
send(buyer, Pair(notary.notaryIdentity, price))
|
||||
val me = if (anonymous) {
|
||||
serviceHub.keyManagementService.freshKeyAndCert(serviceHub.myInfo.legalIdentityAndCert, false)
|
||||
} else {
|
||||
serviceHub.myInfo.legalIdentityAndCert
|
||||
}
|
||||
send(buyer, TestTx(notary.notaryIdentity, price, anonymous))
|
||||
return subFlow(Seller(
|
||||
buyer,
|
||||
notary,
|
||||
@ -562,14 +573,17 @@ class TwoPartyTradeFlowTests {
|
||||
class BuyerAcceptor(val seller: Party) : FlowLogic<SignedTransaction>() {
|
||||
@Suspendable
|
||||
override fun call(): SignedTransaction {
|
||||
val (notary, price) = receive<Pair<Party, Amount<Currency>>>(seller).unwrap {
|
||||
require(serviceHub.networkMapCache.isNotary(it.first)) { "${it.first} is not a notary" }
|
||||
val (notary, price, anonymous) = receive<TestTx>(seller).unwrap {
|
||||
require(serviceHub.networkMapCache.isNotary(it.notaryIdentity)) { "${it.notaryIdentity} is not a notary" }
|
||||
it
|
||||
}
|
||||
return subFlow(Buyer(seller, notary, price, CommercialPaper.State::class.java))
|
||||
return subFlow(Buyer(seller, notary, price, CommercialPaper.State::class.java, anonymous))
|
||||
}
|
||||
}
|
||||
|
||||
@CordaSerializable
|
||||
data class TestTx(val notaryIdentity: Party, val price: Amount<Currency>, val anonymous: Boolean)
|
||||
|
||||
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.runWithError(
|
||||
bobError: Boolean,
|
||||
aliceError: Boolean,
|
||||
@ -581,6 +595,12 @@ class TwoPartyTradeFlowTests {
|
||||
val bankNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOC.name)
|
||||
val issuer = bankNode.info.legalIdentity.ref(1, 2, 3)
|
||||
|
||||
// Let the nodes know about each other - normally the network map would handle this
|
||||
val allNodes = listOf(notaryNode, aliceNode, bobNode, bankNode)
|
||||
allNodes.forEach { node ->
|
||||
allNodes.map { it.services.myInfo.legalIdentityAndCert }.forEach { identity -> node.services.identityService.registerIdentity(identity) }
|
||||
}
|
||||
|
||||
val bobsBadCash = bobNode.database.transaction {
|
||||
fillUpForBuyer(bobError, issuer, bobNode.info.legalIdentity,
|
||||
notaryNode.info.notaryIdentity).second
|
||||
|
Reference in New Issue
Block a user