mirror of
https://github.com/corda/corda.git
synced 2025-01-24 13:28:07 +00:00
CORDA-654: Migrate test APIs to match identity changes (#1744)
Rework identity usage in tests to extract identity from nodes by name, rather than just arbitrarily choosing the first identity. This better models the intended design for production (future work).
This commit is contained in:
parent
ed79db6864
commit
327f0ebd73
@ -19,8 +19,8 @@ class SwapIdentitiesFlowTests {
|
||||
val notaryNode = mockNet.createNotaryNode()
|
||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
val bobNode = mockNet.createPartyNode(BOB.name)
|
||||
val alice: Party = aliceNode.services.myInfo.chooseIdentity()
|
||||
val bob: Party = bobNode.services.myInfo.chooseIdentity()
|
||||
val alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
|
||||
val bob = bobNode.services.myInfo.identityFromX500Name(BOB_NAME)
|
||||
|
||||
// Run the flows
|
||||
val requesterFlow = aliceNode.services.startFlow(SwapIdentitiesFlow(bob))
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.core.node
|
||||
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
@ -42,4 +43,9 @@ data class NodeInfo(val addresses: List<NetworkHostAndPort>,
|
||||
|
||||
/** Returns true if [party] is one of the identities of this node, else false. */
|
||||
fun isLegalIdentity(party: Party): Boolean = party in legalIdentities
|
||||
|
||||
fun identityFromX500Name(name: CordaX500Name): Party {
|
||||
val identity = legalIdentitiesAndCerts.singleOrNull { it.name == name } ?: throw IllegalArgumentException("Node does not have an identity \"$name\"")
|
||||
return identity.party
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ import net.corda.node.services.persistence.NodeAttachmentService
|
||||
import net.corda.node.utilities.DatabaseTransactionManager
|
||||
import net.corda.nodeapi.internal.ServiceInfo
|
||||
import net.corda.testing.ALICE
|
||||
import net.corda.testing.ALICE_NAME
|
||||
import net.corda.testing.BOB
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@ -55,13 +55,13 @@ class AttachmentTests {
|
||||
|
||||
@Test
|
||||
fun `download and store`() {
|
||||
mockNet.createNotaryNode()
|
||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
val bobNode = mockNet.createPartyNode(BOB.name)
|
||||
|
||||
// Ensure that registration was successful before progressing any further
|
||||
mockNet.runNetwork()
|
||||
aliceNode.internals.ensureRegistered()
|
||||
val alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
|
||||
|
||||
aliceNode.internals.registerInitiatedFlow(FetchAttachmentsResponse::class.java)
|
||||
bobNode.internals.registerInitiatedFlow(FetchAttachmentsResponse::class.java)
|
||||
@ -73,7 +73,7 @@ class AttachmentTests {
|
||||
|
||||
// Get node one to run a flow to fetch it and insert it.
|
||||
mockNet.runNetwork()
|
||||
val bobFlow = bobNode.startAttachmentFlow(setOf(id), aliceNode.info.chooseIdentity())
|
||||
val bobFlow = bobNode.startAttachmentFlow(setOf(id), alice)
|
||||
mockNet.runNetwork()
|
||||
assertEquals(0, bobFlow.resultFuture.getOrThrow().fromDisk.size)
|
||||
|
||||
@ -87,13 +87,12 @@ class AttachmentTests {
|
||||
// Shut down node zero and ensure node one can still resolve the attachment.
|
||||
aliceNode.dispose()
|
||||
|
||||
val response: FetchDataFlow.Result<Attachment> = bobNode.startAttachmentFlow(setOf(id), aliceNode.info.chooseIdentity()).resultFuture.getOrThrow()
|
||||
val response: FetchDataFlow.Result<Attachment> = bobNode.startAttachmentFlow(setOf(id), alice).resultFuture.getOrThrow()
|
||||
assertEquals(attachment, response.fromDisk[0])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `missing`() {
|
||||
mockNet.createNotaryNode()
|
||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
val bobNode = mockNet.createPartyNode(BOB.name)
|
||||
|
||||
@ -107,7 +106,8 @@ class AttachmentTests {
|
||||
// Get node one to fetch a non-existent attachment.
|
||||
val hash = SecureHash.randomSHA256()
|
||||
mockNet.runNetwork()
|
||||
val bobFlow = bobNode.startAttachmentFlow(setOf(hash), aliceNode.info.chooseIdentity())
|
||||
val alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
|
||||
val bobFlow = bobNode.startAttachmentFlow(setOf(hash), alice)
|
||||
mockNet.runNetwork()
|
||||
val e = assertFailsWith<FetchDataFlow.HashNotFound> { bobFlow.resultFuture.getOrThrow() }
|
||||
assertEquals(hash, e.requested)
|
||||
@ -130,6 +130,7 @@ class AttachmentTests {
|
||||
// Ensure that registration was successful before progressing any further
|
||||
mockNet.runNetwork()
|
||||
aliceNode.internals.ensureRegistered()
|
||||
val alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
|
||||
|
||||
aliceNode.internals.registerInitiatedFlow(FetchAttachmentsResponse::class.java)
|
||||
bobNode.internals.registerInitiatedFlow(FetchAttachmentsResponse::class.java)
|
||||
@ -151,7 +152,7 @@ class AttachmentTests {
|
||||
|
||||
// Get n1 to fetch the attachment. Should receive corrupted bytes.
|
||||
mockNet.runNetwork()
|
||||
val bobFlow = bobNode.startAttachmentFlow(setOf(id), aliceNode.info.chooseIdentity())
|
||||
val bobFlow = bobNode.startAttachmentFlow(setOf(id), alice)
|
||||
mockNet.runNetwork()
|
||||
assertFailsWith<FetchDataFlow.DownloadedVsRequestedDataMismatch> { bobFlow.resultFuture.getOrThrow() }
|
||||
}
|
||||
|
@ -31,6 +31,9 @@ class CollectSignaturesFlowTests {
|
||||
lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
|
||||
lateinit var bobNode: StartedNode<MockNetwork.MockNode>
|
||||
lateinit var charlieNode: StartedNode<MockNetwork.MockNode>
|
||||
lateinit var alice: Party
|
||||
lateinit var bob: Party
|
||||
lateinit var charlie: Party
|
||||
lateinit var notary: Party
|
||||
|
||||
@Before
|
||||
@ -41,8 +44,11 @@ class CollectSignaturesFlowTests {
|
||||
bobNode = mockNet.createPartyNode(BOB.name)
|
||||
charlieNode = mockNet.createPartyNode(CHARLIE.name)
|
||||
mockNet.runNetwork()
|
||||
notary = notaryNode.services.getDefaultNotary()
|
||||
aliceNode.internals.ensureRegistered()
|
||||
alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
|
||||
bob = bobNode.services.myInfo.identityFromX500Name(BOB_NAME)
|
||||
charlie = charlieNode.services.myInfo.identityFromX500Name(CHARLIE_NAME)
|
||||
notary = notaryNode.services.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME)!!
|
||||
}
|
||||
|
||||
@After
|
||||
@ -143,7 +149,8 @@ class CollectSignaturesFlowTests {
|
||||
@Test
|
||||
fun `successfully collects two signatures`() {
|
||||
val bConfidentialIdentity = bobNode.database.transaction {
|
||||
bobNode.services.keyManagementService.freshKeyAndCert(bobNode.info.chooseIdentityAndCert(), false)
|
||||
val bobCert = bobNode.services.myInfo.legalIdentitiesAndCerts.single { it.name == bob.name }
|
||||
bobNode.services.keyManagementService.freshKeyAndCert(bobCert, false)
|
||||
}
|
||||
aliceNode.database.transaction {
|
||||
// Normally this is handled by TransactionKeyFlow, but here we have to manually let A know about the identity
|
||||
@ -151,7 +158,7 @@ class CollectSignaturesFlowTests {
|
||||
}
|
||||
registerFlowOnAllNodes(TestFlowTwo.Responder::class)
|
||||
val magicNumber = 1337
|
||||
val parties = listOf(aliceNode.info.chooseIdentity(), bConfidentialIdentity.party, charlieNode.info.chooseIdentity())
|
||||
val parties = listOf(alice, bConfidentialIdentity.party, charlie)
|
||||
val state = DummyContract.MultiOwnerState(magicNumber, parties)
|
||||
val flow = aliceNode.services.startFlow(TestFlowTwo.Initiator(state))
|
||||
mockNet.runNetwork()
|
||||
@ -163,7 +170,7 @@ class CollectSignaturesFlowTests {
|
||||
|
||||
@Test
|
||||
fun `no need to collect any signatures`() {
|
||||
val onePartyDummyContract = DummyContract.generateInitial(1337, notary, aliceNode.info.chooseIdentity().ref(1))
|
||||
val onePartyDummyContract = DummyContract.generateInitial(1337, notary, alice.ref(1))
|
||||
val ptx = aliceNode.services.signInitialTransaction(onePartyDummyContract)
|
||||
val flow = aliceNode.services.startFlow(CollectSignaturesFlow(ptx, emptySet()))
|
||||
mockNet.runNetwork()
|
||||
@ -175,7 +182,7 @@ class CollectSignaturesFlowTests {
|
||||
|
||||
@Test
|
||||
fun `fails when not signed by initiator`() {
|
||||
val onePartyDummyContract = DummyContract.generateInitial(1337, notary, aliceNode.info.chooseIdentity().ref(1))
|
||||
val onePartyDummyContract = DummyContract.generateInitial(1337, notary, alice.ref(1))
|
||||
val miniCorpServices = MockServices(cordappPackages, MINI_CORP_KEY)
|
||||
val ptx = miniCorpServices.signInitialTransaction(onePartyDummyContract)
|
||||
val flow = aliceNode.services.startFlow(CollectSignaturesFlow(ptx, emptySet()))
|
||||
@ -188,9 +195,9 @@ class CollectSignaturesFlowTests {
|
||||
@Test
|
||||
fun `passes with multiple initial signatures`() {
|
||||
val twoPartyDummyContract = DummyContract.generateInitial(1337, notary,
|
||||
aliceNode.info.chooseIdentity().ref(1),
|
||||
bobNode.info.chooseIdentity().ref(2),
|
||||
bobNode.info.chooseIdentity().ref(3))
|
||||
alice.ref(1),
|
||||
bob.ref(2),
|
||||
bob.ref(3))
|
||||
val signedByA = aliceNode.services.signInitialTransaction(twoPartyDummyContract)
|
||||
val signedByBoth = bobNode.services.addSignature(signedByA)
|
||||
val flow = aliceNode.services.startFlow(CollectSignaturesFlow(signedByBoth, emptySet()))
|
||||
|
@ -6,7 +6,7 @@ import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.finance.POUNDS
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.issuedBy
|
||||
import net.corda.node.internal.StartedNode
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import org.junit.After
|
||||
@ -16,20 +16,26 @@ import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
|
||||
class FinalityFlowTests {
|
||||
lateinit var mockNet: MockNetwork
|
||||
lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
|
||||
lateinit var bobNode: StartedNode<MockNetwork.MockNode>
|
||||
lateinit var notary: Party
|
||||
private lateinit var mockNet: MockNetwork
|
||||
private lateinit var aliceServices: ServiceHubInternal
|
||||
private lateinit var bobServices: ServiceHubInternal
|
||||
private lateinit var alice: Party
|
||||
private lateinit var bob: Party
|
||||
private lateinit var notary: Party
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
||||
mockNet.createNotaryNode()
|
||||
aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
bobNode = mockNet.createPartyNode(BOB.name)
|
||||
val notaryNode = mockNet.createNotaryNode()
|
||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||
mockNet.runNetwork()
|
||||
aliceNode.internals.ensureRegistered()
|
||||
notary = aliceNode.services.getDefaultNotary()
|
||||
aliceServices = aliceNode.services
|
||||
bobServices = bobNode.services
|
||||
alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
|
||||
bob = bobNode.services.myInfo.identityFromX500Name(BOB_NAME)
|
||||
notary = notaryNode.services.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME)!!
|
||||
}
|
||||
|
||||
@After
|
||||
@ -39,28 +45,28 @@ class FinalityFlowTests {
|
||||
|
||||
@Test
|
||||
fun `finalise a simple transaction`() {
|
||||
val amount = 1000.POUNDS.issuedBy(aliceNode.info.chooseIdentity().ref(0))
|
||||
val amount = 1000.POUNDS.issuedBy(alice.ref(0))
|
||||
val builder = TransactionBuilder(notary)
|
||||
Cash().generateIssue(builder, amount, bobNode.info.chooseIdentity(), notary)
|
||||
val stx = aliceNode.services.signInitialTransaction(builder)
|
||||
val flow = aliceNode.services.startFlow(FinalityFlow(stx))
|
||||
Cash().generateIssue(builder, amount, bob, notary)
|
||||
val stx = aliceServices.signInitialTransaction(builder)
|
||||
val flow = aliceServices.startFlow(FinalityFlow(stx))
|
||||
mockNet.runNetwork()
|
||||
val notarisedTx = flow.resultFuture.getOrThrow()
|
||||
notarisedTx.verifyRequiredSignatures()
|
||||
val transactionSeenByB = bobNode.services.database.transaction {
|
||||
bobNode.services.validatedTransactions.getTransaction(notarisedTx.id)
|
||||
val transactionSeenByB = bobServices.database.transaction {
|
||||
bobServices.validatedTransactions.getTransaction(notarisedTx.id)
|
||||
}
|
||||
assertEquals(notarisedTx, transactionSeenByB)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `reject a transaction with unknown parties`() {
|
||||
val amount = 1000.POUNDS.issuedBy(aliceNode.info.chooseIdentity().ref(0))
|
||||
val amount = 1000.POUNDS.issuedBy(alice.ref(0))
|
||||
val fakeIdentity = CHARLIE // Charlie 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 = aliceNode.services.signInitialTransaction(builder)
|
||||
val flow = aliceNode.services.startFlow(FinalityFlow(stx))
|
||||
val stx = aliceServices.signInitialTransaction(builder)
|
||||
val flow = aliceServices.startFlow(FinalityFlow(stx))
|
||||
mockNet.runNetwork()
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
flow.resultFuture.getOrThrow()
|
||||
|
@ -3,14 +3,14 @@ package net.corda.docs
|
||||
import net.corda.core.contracts.LinearState
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.UniqueIdentifier
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.services.queryBy
|
||||
import net.corda.core.node.services.vault.QueryCriteria
|
||||
import net.corda.core.toFuture
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.node.internal.StartedNode
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@ -19,8 +19,10 @@ import kotlin.test.assertEquals
|
||||
|
||||
class WorkflowTransactionBuildTutorialTest {
|
||||
lateinit var mockNet: MockNetwork
|
||||
lateinit var nodeA: StartedNode<MockNetwork.MockNode>
|
||||
lateinit var nodeB: StartedNode<MockNetwork.MockNode>
|
||||
lateinit var aliceServices: ServiceHubInternal
|
||||
lateinit var bobServices: ServiceHubInternal
|
||||
lateinit var alice: Party
|
||||
lateinit var bob: Party
|
||||
|
||||
// Helper method to locate the latest Vault version of a LinearState
|
||||
private inline fun <reified T : LinearState> ServiceHub.latest(ref: UniqueIdentifier): StateAndRef<T> {
|
||||
@ -31,10 +33,15 @@ class WorkflowTransactionBuildTutorialTest {
|
||||
@Before
|
||||
fun setup() {
|
||||
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.docs"))
|
||||
// While we don't use the notary, we need there to be one on the network
|
||||
mockNet.createNotaryNode(legalName = DUMMY_NOTARY.name)
|
||||
nodeA = mockNet.createPartyNode()
|
||||
nodeB = mockNet.createPartyNode()
|
||||
nodeA.internals.registerInitiatedFlow(RecordCompletionFlow::class.java)
|
||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||
aliceNode.internals.registerInitiatedFlow(RecordCompletionFlow::class.java)
|
||||
aliceServices = aliceNode.services
|
||||
bobServices = bobNode.services
|
||||
alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
|
||||
bob = bobNode.services.myInfo.identityFromX500Name(BOB_NAME)
|
||||
}
|
||||
|
||||
@After
|
||||
@ -45,50 +52,50 @@ class WorkflowTransactionBuildTutorialTest {
|
||||
@Test
|
||||
fun `Run workflow to completion`() {
|
||||
// Setup a vault subscriber to wait for successful upload of the proposal to NodeB
|
||||
val nodeBVaultUpdate = nodeB.services.vaultService.updates.toFuture()
|
||||
val nodeBVaultUpdate = bobServices.vaultService.updates.toFuture()
|
||||
// Kick of the proposal flow
|
||||
val flow1 = nodeA.services.startFlow(SubmitTradeApprovalFlow("1234", nodeB.info.chooseIdentity()))
|
||||
val flow1 = aliceServices.startFlow(SubmitTradeApprovalFlow("1234", bob))
|
||||
// Wait for the flow to finish
|
||||
val proposalRef = flow1.resultFuture.getOrThrow()
|
||||
val proposalLinearId = proposalRef.state.data.linearId
|
||||
// Wait for NodeB to include it's copy in the vault
|
||||
nodeBVaultUpdate.get()
|
||||
// Fetch the latest copy of the state from both nodes
|
||||
val latestFromA = nodeA.database.transaction {
|
||||
nodeA.services.latest<TradeApprovalContract.State>(proposalLinearId)
|
||||
val latestFromA = aliceServices.database.transaction {
|
||||
aliceServices.latest<TradeApprovalContract.State>(proposalLinearId)
|
||||
}
|
||||
val latestFromB = nodeB.database.transaction {
|
||||
nodeB.services.latest<TradeApprovalContract.State>(proposalLinearId)
|
||||
val latestFromB = bobServices.database.transaction {
|
||||
bobServices.latest<TradeApprovalContract.State>(proposalLinearId)
|
||||
}
|
||||
// Confirm the state as as expected
|
||||
assertEquals(WorkflowState.NEW, proposalRef.state.data.state)
|
||||
assertEquals("1234", proposalRef.state.data.tradeId)
|
||||
assertEquals(nodeA.info.chooseIdentity(), proposalRef.state.data.source)
|
||||
assertEquals(nodeB.info.chooseIdentity(), proposalRef.state.data.counterparty)
|
||||
assertEquals(alice, proposalRef.state.data.source)
|
||||
assertEquals(bob, proposalRef.state.data.counterparty)
|
||||
assertEquals(proposalRef, latestFromA)
|
||||
assertEquals(proposalRef, latestFromB)
|
||||
// Setup a vault subscriber to pause until the final update is in NodeA and NodeB
|
||||
val nodeAVaultUpdate = nodeA.services.vaultService.updates.toFuture()
|
||||
val secondNodeBVaultUpdate = nodeB.services.vaultService.updates.toFuture()
|
||||
val nodeAVaultUpdate = aliceServices.vaultService.updates.toFuture()
|
||||
val secondNodeBVaultUpdate = bobServices.vaultService.updates.toFuture()
|
||||
// Run the manual completion flow from NodeB
|
||||
val flow2 = nodeB.services.startFlow(SubmitCompletionFlow(latestFromB.ref, WorkflowState.APPROVED))
|
||||
val flow2 = bobServices.startFlow(SubmitCompletionFlow(latestFromB.ref, WorkflowState.APPROVED))
|
||||
// wait for the flow to end
|
||||
val completedRef = flow2.resultFuture.getOrThrow()
|
||||
// wait for the vault updates to stabilise
|
||||
nodeAVaultUpdate.get()
|
||||
secondNodeBVaultUpdate.get()
|
||||
// Fetch the latest copies from the vault
|
||||
val finalFromA = nodeA.database.transaction {
|
||||
nodeA.services.latest<TradeApprovalContract.State>(proposalLinearId)
|
||||
val finalFromA = aliceServices.database.transaction {
|
||||
aliceServices.latest<TradeApprovalContract.State>(proposalLinearId)
|
||||
}
|
||||
val finalFromB = nodeB.database.transaction {
|
||||
nodeB.services.latest<TradeApprovalContract.State>(proposalLinearId)
|
||||
val finalFromB = bobServices.database.transaction {
|
||||
bobServices.latest<TradeApprovalContract.State>(proposalLinearId)
|
||||
}
|
||||
// Confirm the state is as expected
|
||||
assertEquals(WorkflowState.APPROVED, completedRef.state.data.state)
|
||||
assertEquals("1234", completedRef.state.data.tradeId)
|
||||
assertEquals(nodeA.info.chooseIdentity(), completedRef.state.data.source)
|
||||
assertEquals(nodeB.info.chooseIdentity(), completedRef.state.data.counterparty)
|
||||
assertEquals(alice, completedRef.state.data.source)
|
||||
assertEquals(bob, completedRef.state.data.counterparty)
|
||||
assertEquals(completedRef, finalFromA)
|
||||
assertEquals(completedRef, finalFromB)
|
||||
}
|
||||
|
@ -7,11 +7,13 @@ import net.corda.core.flows.NotaryFlow
|
||||
import net.corda.core.flows.StateReplacementException
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.node.internal.StartedNode
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
import net.corda.testing.node.MockNetwork
|
||||
@ -39,11 +41,11 @@ class NotaryChangeTests {
|
||||
oldNotaryNode = mockNet.createNotaryNode(legalName = DUMMY_NOTARY.name)
|
||||
clientNodeA = mockNet.createNode()
|
||||
clientNodeB = mockNet.createNode()
|
||||
newNotaryNode = mockNet.createNotaryNode()
|
||||
newNotaryNode = mockNet.createNotaryNode(legalName = DUMMY_NOTARY.name.copy(organisation = "Dummy Notary 2"))
|
||||
mockNet.runNetwork() // Clear network map registration messages
|
||||
oldNotaryNode.internals.ensureRegistered()
|
||||
newNotaryParty = newNotaryNode.info.legalIdentities[1]
|
||||
oldNotaryParty = oldNotaryNode.info.legalIdentities[1]
|
||||
oldNotaryParty = newNotaryNode.services.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME)!!
|
||||
newNotaryParty = newNotaryNode.services.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME.copy(organisation = "Dummy Notary 2"))!!
|
||||
}
|
||||
|
||||
@After
|
||||
@ -211,10 +213,10 @@ fun issueMultiPartyState(nodeA: StartedNode<*>, nodeB: StartedNode<*>, notaryNod
|
||||
return stx.tx.outRef(0)
|
||||
}
|
||||
|
||||
fun issueInvalidState(node: StartedNode<*>, notary: Party): StateAndRef<DummyContract.SingleOwnerState> {
|
||||
val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.chooseIdentity().ref(0))
|
||||
fun issueInvalidState(services: ServiceHub, identity: Party, notary: Party): StateAndRef<DummyContract.SingleOwnerState> {
|
||||
val tx = DummyContract.generateInitial(Random().nextInt(), notary, identity.ref(0))
|
||||
tx.setTimeWindow(Instant.now(), 30.seconds)
|
||||
val stx = node.services.signInitialTransaction(tx)
|
||||
node.services.recordTransactions(stx)
|
||||
val stx = services.signInitialTransaction(tx)
|
||||
services.recordTransactions(stx)
|
||||
return stx.tx.outRef(0)
|
||||
}
|
@ -9,10 +9,11 @@ import net.corda.core.flows.NotaryError
|
||||
import net.corda.core.flows.NotaryException
|
||||
import net.corda.core.flows.NotaryFlow
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.node.internal.StartedNode
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
import net.corda.node.services.issueInvalidState
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
@ -27,18 +28,22 @@ import kotlin.test.assertFailsWith
|
||||
|
||||
class ValidatingNotaryServiceTests {
|
||||
lateinit var mockNet: MockNetwork
|
||||
lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
|
||||
lateinit var clientNode: StartedNode<MockNetwork.MockNode>
|
||||
lateinit var notaryServices: ServiceHubInternal
|
||||
lateinit var aliceServices: ServiceHubInternal
|
||||
lateinit var notary: Party
|
||||
lateinit var alice: Party
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts"))
|
||||
notaryNode = mockNet.createNotaryNode(legalName = DUMMY_NOTARY.name)
|
||||
clientNode = mockNet.createNode()
|
||||
val notaryNode = mockNet.createNotaryNode(legalName = DUMMY_NOTARY.name)
|
||||
val aliceNode = mockNet.createNode(legalName = ALICE_NAME)
|
||||
mockNet.runNetwork() // Clear network map registration messages
|
||||
notaryNode.internals.ensureRegistered()
|
||||
notary = clientNode.services.getDefaultNotary()
|
||||
notaryServices = notaryNode.services
|
||||
aliceServices = aliceNode.services
|
||||
notary = notaryServices.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME)!!
|
||||
alice = aliceServices.myInfo.identityFromX500Name(ALICE_NAME)
|
||||
}
|
||||
|
||||
@After
|
||||
@ -49,11 +54,11 @@ class ValidatingNotaryServiceTests {
|
||||
@Test
|
||||
fun `should report error for invalid transaction dependency`() {
|
||||
val stx = run {
|
||||
val inputState = issueInvalidState(clientNode, notary)
|
||||
val inputState = issueInvalidState(aliceServices, alice, notary)
|
||||
val tx = TransactionBuilder(notary)
|
||||
.addInputState(inputState)
|
||||
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
.addCommand(dummyCommand(alice.owningKey))
|
||||
aliceServices.signInitialTransaction(tx)
|
||||
}
|
||||
|
||||
val future = runClient(stx)
|
||||
@ -67,11 +72,11 @@ class ValidatingNotaryServiceTests {
|
||||
fun `should report error for missing signatures`() {
|
||||
val expectedMissingKey = MEGA_CORP_KEY.public
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val inputState = issueState(aliceServices, alice)
|
||||
|
||||
val command = Command(DummyContract.Commands.Move(), expectedMissingKey)
|
||||
val tx = TransactionBuilder(notary).withItems(inputState, command)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
aliceServices.signInitialTransaction(tx)
|
||||
}
|
||||
|
||||
val ex = assertFailsWith(NotaryException::class) {
|
||||
@ -87,16 +92,16 @@ class ValidatingNotaryServiceTests {
|
||||
|
||||
private fun runClient(stx: SignedTransaction): CordaFuture<List<TransactionSignature>> {
|
||||
val flow = NotaryFlow.Client(stx)
|
||||
val future = clientNode.services.startFlow(flow).resultFuture
|
||||
val future = aliceServices.startFlow(flow).resultFuture
|
||||
mockNet.runNetwork()
|
||||
return future
|
||||
}
|
||||
|
||||
fun issueState(node: StartedNode<*>): StateAndRef<*> {
|
||||
val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.chooseIdentity().ref(0))
|
||||
val signedByNode = node.services.signInitialTransaction(tx)
|
||||
val stx = notaryNode.services.addSignature(signedByNode, notary.owningKey)
|
||||
node.services.recordTransactions(stx)
|
||||
fun issueState(serviceHub: ServiceHub, identity: Party): StateAndRef<*> {
|
||||
val tx = DummyContract.generateInitial(Random().nextInt(), notary, identity.ref(0))
|
||||
val signedByNode = serviceHub.signInitialTransaction(tx)
|
||||
val stx = notaryServices.addSignature(signedByNode, notary.owningKey)
|
||||
serviceHub.recordTransactions(stx)
|
||||
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
|
||||
}
|
||||
}
|
||||
|
@ -41,12 +41,14 @@ class BankOfCordaRPCClientTest {
|
||||
// Register for Big Corporation Vault updates
|
||||
val vaultUpdatesBigCorp = bigCorpProxy.vaultTrackByCriteria(Cash.State::class.java, criteria).updates
|
||||
|
||||
val bigCorporation = bigCorpProxy.wellKnownPartyFromX500Name(BIGCORP_LEGAL_NAME)!!
|
||||
|
||||
// Kick-off actual Issuer Flow
|
||||
val anonymous = true
|
||||
val notary = bocProxy.notaryIdentities().first()
|
||||
bocProxy.startFlow(::CashIssueAndPaymentFlow,
|
||||
1000.DOLLARS, BIG_CORP_PARTY_REF,
|
||||
nodeBigCorporation.nodeInfo.chooseIdentity(),
|
||||
bigCorporation,
|
||||
anonymous,
|
||||
notary).returnValue.getOrThrow()
|
||||
|
||||
|
@ -44,12 +44,9 @@ import net.corda.node.utilities.AffinityExecutor
|
||||
import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor
|
||||
import net.corda.node.utilities.CertificateAndKeyPair
|
||||
import net.corda.nodeapi.internal.ServiceInfo
|
||||
import net.corda.testing.DUMMY_KEY_1
|
||||
import net.corda.testing.initialiseTestSerialization
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
|
||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||
import net.corda.testing.resetTestSerialization
|
||||
import net.corda.testing.testNodeConfiguration
|
||||
import org.apache.activemq.artemis.utils.ReusableLatch
|
||||
import org.slf4j.Logger
|
||||
import java.io.Closeable
|
||||
@ -393,13 +390,13 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun createNotaryNode(legalName: CordaX500Name? = null, validating: Boolean = true): StartedNode<MockNode> {
|
||||
fun createNotaryNode(legalName: CordaX500Name = DUMMY_NOTARY.name, validating: Boolean = true): StartedNode<MockNode> {
|
||||
return createNode(legalName = legalName, configOverrides = {
|
||||
whenever(it.notary).thenReturn(NotaryConfig(validating))
|
||||
})
|
||||
}
|
||||
|
||||
fun <N : MockNode> createNotaryNode(legalName: CordaX500Name? = null,
|
||||
fun <N : MockNode> createNotaryNode(legalName: CordaX500Name = DUMMY_NOTARY.name,
|
||||
validating: Boolean = true,
|
||||
nodeFactory: Factory<N>): StartedNode<N> {
|
||||
return createNode(legalName = legalName, nodeFactory = nodeFactory, configOverrides = {
|
||||
|
@ -31,6 +31,7 @@ val DUMMY_NOTARY_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(20))
|
||||
/** Dummy notary identity for tests and simulations */
|
||||
val DUMMY_NOTARY_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(DUMMY_NOTARY)
|
||||
val DUMMY_NOTARY: Party get() = Party(CordaX500Name(organisation = "Notary Service", locality = "Zurich", country = "CH"), DUMMY_NOTARY_KEY.public)
|
||||
val DUMMY_NOTARY_SERVICE_NAME: CordaX500Name = DUMMY_NOTARY.name.copy(commonName = "corda.notary.validating")
|
||||
|
||||
val DUMMY_MAP_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(30)) }
|
||||
/** Dummy network map service identity for tests and simulations */
|
||||
@ -51,17 +52,20 @@ val DUMMY_BANK_C: Party get() = Party(CordaX500Name(organisation = "Bank C", loc
|
||||
val ALICE_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(70)) }
|
||||
/** Dummy individual identity for tests and simulations */
|
||||
val ALICE_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(ALICE)
|
||||
val ALICE: Party get() = Party(CordaX500Name(organisation = "Alice Corp", locality = "Madrid", country = "ES"), ALICE_KEY.public)
|
||||
val ALICE_NAME = CordaX500Name(organisation = "Alice Corp", locality = "Madrid", country = "ES")
|
||||
val ALICE: Party get() = Party(ALICE_NAME, ALICE_KEY.public)
|
||||
|
||||
val BOB_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(80)) }
|
||||
/** Dummy individual identity for tests and simulations */
|
||||
val BOB_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(BOB)
|
||||
val BOB: Party get() = Party(CordaX500Name(organisation = "Bob Plc", locality = "Rome", country = "IT"), BOB_KEY.public)
|
||||
val BOB_NAME = CordaX500Name(organisation = "Bob Plc", locality = "Rome", country = "IT")
|
||||
val BOB: Party get() = Party(BOB_NAME, BOB_KEY.public)
|
||||
|
||||
val CHARLIE_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(90)) }
|
||||
/** Dummy individual identity for tests and simulations */
|
||||
val CHARLIE_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(CHARLIE)
|
||||
val CHARLIE: Party get() = Party(CordaX500Name(organisation = "Charlie Ltd", locality = "Athens", country = "GR"), CHARLIE_KEY.public)
|
||||
val CHARLIE_NAME = CordaX500Name(organisation = "Charlie Ltd", locality = "Athens", country = "GR")
|
||||
val CHARLIE: Party get() = Party(CHARLIE_NAME, CHARLIE_KEY.public)
|
||||
|
||||
val DUMMY_REGULATOR_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(100)) }
|
||||
/** Dummy regulator for tests and simulations */
|
||||
|
@ -13,6 +13,9 @@ import net.corda.node.services.config.VerifierType
|
||||
import net.corda.testing.ALICE
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.node.services.transactions.ValidatingNotaryService
|
||||
import net.corda.nodeapi.internal.ServiceInfo
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.driver.NetworkMapStartStrategy
|
||||
import org.junit.Test
|
||||
import java.util.*
|
||||
@ -116,14 +119,15 @@ class VerifierTests {
|
||||
) {
|
||||
val aliceFuture = startNode(providedName = ALICE.name)
|
||||
val notaryFuture = startNotaryNode(DUMMY_NOTARY.name, verifierType = VerifierType.OutOfProcess)
|
||||
val alice = aliceFuture.get()
|
||||
val notary = notaryFuture.get()
|
||||
val notaryIdentity = notary.nodeInfo.legalIdentities[1]
|
||||
startVerifier(notary)
|
||||
alice.rpc.startFlow(::CashIssueFlow, 10.DOLLARS, OpaqueBytes.of(0), notaryIdentity).returnValue.get()
|
||||
notary.waitUntilNumberOfVerifiers(1)
|
||||
val aliceNode = aliceFuture.get()
|
||||
val notaryNode = notaryFuture.get()
|
||||
val alice = notaryNode.rpc.wellKnownPartyFromX500Name(ALICE_NAME)!!
|
||||
val notary = notaryNode.rpc.notaryPartyFromX500Name(DUMMY_NOTARY_SERVICE_NAME)!!
|
||||
startVerifier(notaryNode)
|
||||
aliceNode.rpc.startFlow(::CashIssueFlow, 10.DOLLARS, OpaqueBytes.of(0), notary).returnValue.get()
|
||||
notaryNode.waitUntilNumberOfVerifiers(1)
|
||||
for (i in 1..10) {
|
||||
alice.rpc.startFlow(::CashPaymentFlow, 10.DOLLARS, alice.nodeInfo.chooseIdentity()).returnValue.get()
|
||||
aliceNode.rpc.startFlow(::CashPaymentFlow, 10.DOLLARS, alice).returnValue.get()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user