Move tests to using named identities (#1879)

Move tests to using named identities in preparation for multiple identities work. Includes:

* NetworkMapCacheTest
* NodeInterestRatesTest
* NodeVaultServiceTest
* ContractUpgradeFlowTest
* Cash tests
* AttachmentSerializationTest
* CordaRPCOpsImplTest
* VaultWithCashTest
* ScheduledFlowTests
This commit is contained in:
Ross Nicoll
2017-11-17 14:16:17 +00:00
committed by GitHub
parent 9d6d027523
commit 19aba62fc6
22 changed files with 254 additions and 179 deletions

View File

@ -34,6 +34,7 @@ import net.corda.node.services.messaging.RpcPermissions
import net.corda.testing.*
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode
import net.corda.testing.node.MockNodeParameters
import org.apache.commons.io.IOUtils
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.After
@ -54,6 +55,7 @@ class CordaRPCOpsImplTest {
private lateinit var mockNet: MockNetwork
private lateinit var aliceNode: StartedNode<MockNode>
private lateinit var alice: Party
private lateinit var notary: Party
private lateinit var rpc: CordaRPCOps
private lateinit var stateMachineUpdates: Observable<StateMachineUpdate>
@ -63,14 +65,15 @@ class CordaRPCOpsImplTest {
@Before
fun setup() {
mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset"))
aliceNode = mockNet.createNode()
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
rpc = SecureCordaRPCOps(aliceNode.services, aliceNode.smm, aliceNode.database, aliceNode.services)
CURRENT_RPC_CONTEXT.set(RpcAuthContext(InvocationContext.rpc(testActor()), RpcPermissions.NONE))
mockNet.runNetwork()
withPermissions(invokeRpc(CordaRPCOps::notaryIdentities)) {
notary = rpc.notaryIdentities().first()
notary = rpc.notaryIdentities().single()
}
alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
}
@After
@ -115,7 +118,7 @@ class CordaRPCOpsImplTest {
val anonymisedRecipient = result.returnValue.getOrThrow().recipient!!
val expectedState = Cash.State(Amount(quantity,
Issued(aliceNode.info.chooseIdentity().ref(ref), GBP)),
Issued(alice.ref(ref), GBP)),
anonymisedRecipient)
// Query vault via RPC
@ -153,7 +156,7 @@ class CordaRPCOpsImplTest {
mockNet.runNetwork()
rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, aliceNode.info.chooseIdentity())
rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, alice)
mockNet.runNetwork()
@ -187,7 +190,7 @@ class CordaRPCOpsImplTest {
require(stx.tx.outputs.size == 1)
val signaturePubKeys = stx.sigs.map { it.by }.toSet()
// Only Alice signed, as issuer
val aliceKey = aliceNode.info.chooseIdentity().owningKey
val aliceKey = alice.owningKey
require(signaturePubKeys.size <= aliceKey.keys.size)
require(aliceKey.isFulfilledBy(signaturePubKeys))
},

View File

@ -97,6 +97,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val bankNode = mockNet.createPartyNode(BOC_NAME)
val alice = aliceNode.info.singleIdentity()
val bank = bankNode.info.singleIdentity()
val bob = bobNode.info.singleIdentity()
val notary = mockNet.defaultNotaryIdentity
val cashIssuer = bank.ref(1)
val cpIssuer = bank.ref(1, 2, 3)
@ -114,9 +115,9 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
1200.DOLLARS `issued by` bank.ref(0), null, notary).second
}
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode,
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, bob, aliceNode, bobNode,
"alice's paper".outputStateAndRef())
// TODO: Verify that the result was inserted into the transaction database.
@ -147,6 +148,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val bankNode = mockNet.createPartyNode(BOC_NAME)
val alice = aliceNode.info.singleIdentity()
val bank = bankNode.info.singleIdentity()
val bob = bobNode.info.singleIdentity()
val issuer = bank.ref(1)
val notary = mockNet.defaultNotaryIdentity
@ -163,7 +165,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
1200.DOLLARS `issued by` bank.ref(0), null, notary).second
}
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
val cashLockId = UUID.randomUUID()
bobNode.database.transaction {
@ -174,7 +176,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
}
}
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode,
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, bob, aliceNode, bobNode,
"alice's paper".outputStateAndRef())
assertEquals(aliceResult.getOrThrow(), bobStateMachine.getOrThrow().resultFuture.getOrThrow())
@ -210,6 +212,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val notary = mockNet.defaultNotaryIdentity
val alice = aliceNode.info.singleIdentity()
val bank = bankNode.info.singleIdentity()
val bob = bobNode.info.singleIdentity()
val issuer = bank.ref(1, 2, 3)
bobNode.database.transaction {
@ -220,8 +223,8 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
fillUpForSeller(false, issuer, alice,
1200.DOLLARS `issued by` bank.ref(0), null, notary).second
}
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
val aliceFuture = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerResult
insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
val aliceFuture = runBuyerAndSeller(notary, bob, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerResult
// Everything is on this thread so we can now step through the flow one step at a time.
// Seller Alice already sent a message to Buyer Bob. Pump once:
@ -333,16 +336,16 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val bobsFakeCash = bobNode.database.transaction {
fillUpForBuyer(false, issuer, AnonymousParty(bob.owningKey), notary)
}.second
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode)
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, bob, notaryNode, bankNode)
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, issuer, alice,
1200.DOLLARS `issued by` bank.ref(0), attachmentID, notary).second
}
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
mockNet.runNetwork() // Clear network map registration messages
runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef())
runBuyerAndSeller(notary, bob, aliceNode, bobNode, "alice's paper".outputStateAndRef())
mockNet.runNetwork()
@ -420,6 +423,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val notary = mockNet.defaultNotaryIdentity
val alice: Party = aliceNode.info.singleIdentity()
val bank: Party = bankNode.info.singleIdentity()
val bob = bobNode.info.singleIdentity()
val issuer = bank.ref(1, 2, 3)
ledger(aliceNode.services) {
@ -438,20 +442,20 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val bobsFakeCash = bobNode.database.transaction {
fillUpForBuyer(false, issuer, AnonymousParty(bobsKey), notary)
}.second
insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode)
insertFakeTransactions(bobsFakeCash, bobNode, bob, notaryNode, bankNode)
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, issuer, alice,
1200.DOLLARS `issued by` bank.ref(0), attachmentID, notary).second
}
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
val aliceTxStream = aliceNode.services.validatedTransactions.track().updates
val aliceTxMappings = with(aliceNode) {
database.transaction { services.stateMachineRecordedTransactionMapping.track().updates }
}
val aliceSmId = runBuyerAndSeller(notary, aliceNode, bobNode,
val aliceSmId = runBuyerAndSeller(notary, bob, aliceNode, bobNode,
"alice's paper".outputStateAndRef()).sellerId
mockNet.runNetwork()
@ -511,12 +515,13 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
)
private fun runBuyerAndSeller(notary: Party,
buyer: Party,
sellerNode: StartedNode<MockNetwork.MockNode>,
buyerNode: StartedNode<MockNetwork.MockNode>,
assetToSell: StateAndRef<OwnableState>): RunResult {
val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.internals.registerInitiatedFlow(BuyerAcceptor::class.java)
val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine }
val seller = SellerInitiator(buyerNode.info.chooseIdentity(), notary, assetToSell, 1000.DOLLARS, anonymous)
val seller = SellerInitiator(buyer, notary, assetToSell, 1000.DOLLARS, anonymous)
val sellerResult = sellerNode.services.startFlow(seller).resultFuture
return RunResult(firstBuyerFiber, sellerResult, seller.stateMachine.id)
}
@ -582,10 +587,10 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
fillUpForSeller(aliceError, issuer, alice,1200.DOLLARS `issued by` issuer, null, notary).second
}
insertFakeTransactions(bobsBadCash, bobNode, notaryNode, bankNode)
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
insertFakeTransactions(bobsBadCash, bobNode, bob, notaryNode, bankNode)
insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef())
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, bob, aliceNode, bobNode, "alice's paper".outputStateAndRef())
mockNet.runNetwork()
@ -605,13 +610,14 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
private fun insertFakeTransactions(
wtxToSign: List<WireTransaction>,
node: StartedNode<*>,
identity: Party,
notaryNode: StartedNode<*>,
vararg extraSigningNodes: StartedNode<*>): Map<SecureHash, SignedTransaction> {
val notaryParty = mockNet.defaultNotaryIdentity
val signed = wtxToSign.map {
val id = it.id
val sigs = mutableListOf<TransactionSignature>()
val nodeKey = node.info.chooseIdentity().owningKey
val nodeKey = identity.owningKey
sigs += node.services.keyManagementService.sign(
SignableData(id, SignatureMetadata(1, Crypto.findSignatureScheme(nodeKey).schemeNumberID)),
nodeKey
@ -621,11 +627,12 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
notaryParty.owningKey
)
extraSigningNodes.forEach { currentNode ->
val currentIdentity = currentNode.info.singleIdentity()
sigs += currentNode.services.keyManagementService.sign(
SignableData(id, SignatureMetadata(
1,
Crypto.findSignatureScheme(currentNode.info.chooseIdentity().owningKey).schemeNumberID)),
currentNode.info.chooseIdentity().owningKey)
Crypto.findSignatureScheme(currentIdentity.owningKey).schemeNumberID)),
currentIdentity.owningKey)
}
SignedTransaction(it, sigs)
}

View File

@ -17,6 +17,7 @@ import net.corda.testing.*
import net.corda.testing.contracts.DummyContract
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.NotarySpec
import net.corda.testing.node.MockNodeParameters
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.After
import org.junit.Before
@ -37,6 +38,7 @@ class NotaryChangeTests {
private lateinit var clientNodeB: StartedNode<MockNetwork.MockNode>
private lateinit var newNotaryParty: Party
private lateinit var oldNotaryParty: Party
private lateinit var clientA: Party
@Before
fun setUp() {
@ -45,8 +47,9 @@ class NotaryChangeTests {
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name), NotarySpec(oldNotaryName)),
cordappPackages = listOf("net.corda.testing.contracts")
)
clientNodeA = mockNet.createNode()
clientNodeB = mockNet.createNode()
clientNodeA = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
clientNodeB = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
clientA = clientNodeA.info.singleIdentity()
oldNotaryNode = mockNet.notaryNodes[1]
newNotaryParty = clientNodeA.services.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME)!!
oldNotaryParty = clientNodeA.services.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME.copy(organisation = "Old Dummy Notary"))!!
@ -59,7 +62,7 @@ class NotaryChangeTests {
@Test
fun `should change notary for a state with single participant`() {
val state = issueState(clientNodeA, oldNotaryParty)
val state = issueState(clientNodeA.services, clientA, oldNotaryParty)
assertEquals(state.state.notary, oldNotaryParty)
val newState = changeNotary(state, clientNodeA, newNotaryParty)
assertEquals(newState.state.notary, newNotaryParty)
@ -97,7 +100,7 @@ class NotaryChangeTests {
@Test
fun `should not break encumbrance links`() {
val issueTx = issueEncumberedState(clientNodeA, oldNotaryParty)
val issueTx = issueEncumberedState(clientNodeA.services, clientA, oldNotaryParty)
val state = StateAndRef(issueTx.outputs.first(), StateRef(issueTx.id, 0))
val newNotary = newNotaryParty
@ -131,7 +134,7 @@ class NotaryChangeTests {
@Test
fun `notary change and regular transactions are properly handled during resolution in longer chains`() {
val issued = issueState(clientNodeA, oldNotaryParty)
val issued = issueState(clientNodeA.services, clientA, oldNotaryParty)
val moved = moveState(issued, clientNodeA, clientNodeB)
// We don't to tx resolution when moving state to another node, so need to add the issue transaction manually
@ -170,8 +173,8 @@ class NotaryChangeTests {
return finalTransaction.tx.outRef(0)
}
private fun issueEncumberedState(node: StartedNode<*>, notaryIdentity: Party): WireTransaction {
val owner = node.info.chooseIdentity().ref(0)
private fun issueEncumberedState(services: ServiceHub, nodeIdentity: Party, notaryIdentity: Party): WireTransaction {
val owner = nodeIdentity.ref(0)
val stateA = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val stateB = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val stateC = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
@ -182,9 +185,9 @@ class NotaryChangeTests {
addOutputState(stateC, DummyContract.PROGRAM_ID, notaryIdentity)
addOutputState(stateB, DummyContract.PROGRAM_ID, notaryIdentity, encumbrance = 1) // Encumbered by stateC
}
val stx = node.services.signInitialTransaction(tx)
node.services.recordTransactions(stx)
return tx.toWireTransaction(node.services)
val stx = services.signInitialTransaction(tx)
services.recordTransactions(stx)
return tx.toWireTransaction(services)
}
// TODO: Add more test cases once we have a general flow/service exception handling mechanism:
@ -196,10 +199,10 @@ class NotaryChangeTests {
// - The transaction type is not a notary change transaction at all.
}
fun issueState(node: StartedNode<*>, notaryIdentity: Party): StateAndRef<DummyContract.SingleOwnerState> {
val tx = DummyContract.generateInitial(Random().nextInt(), notaryIdentity, node.info.chooseIdentity().ref(0))
val stx = node.services.signInitialTransaction(tx)
node.services.recordTransactions(stx)
fun issueState(services: ServiceHub, nodeIdentity: Party, notaryIdentity: Party): StateAndRef<DummyContract.SingleOwnerState> {
val tx = DummyContract.generateInitial(Random().nextInt(), notaryIdentity, nodeIdentity.ref(0))
val stx = services.signInitialTransaction(tx)
services.recordTransactions(stx)
return stx.tx.outRef(0)
}

View File

@ -2,13 +2,13 @@ package net.corda.node.services.events
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.concurrent.CordaFuture
import net.corda.core.context.Origin
import net.corda.core.contracts.*
import net.corda.core.flows.FinalityFlow
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowLogicRefFactory
import net.corda.core.flows.SchedulableFlow
import net.corda.core.identity.Party
import net.corda.core.context.Origin
import net.corda.core.node.services.VaultService
import net.corda.core.node.services.queryBy
import net.corda.core.node.services.vault.DEFAULT_PAGE_NUM
@ -20,11 +20,10 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode
import net.corda.node.services.statemachine.StateMachineManager
import net.corda.testing.chooseIdentity
import net.corda.testing.*
import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.node.MockNetwork
import net.corda.testing.startFlow
import net.corda.testing.node.MockNodeParameters
import org.junit.After
import org.junit.Assert.*
import org.junit.Before
@ -39,9 +38,11 @@ class ScheduledFlowTests {
}
private lateinit var mockNet: MockNetwork
private lateinit var nodeA: StartedNode<MockNetwork.MockNode>
private lateinit var nodeB: StartedNode<MockNetwork.MockNode>
private lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
private lateinit var bobNode: StartedNode<MockNetwork.MockNode>
private lateinit var notary: Party
private lateinit var alice: Party
private lateinit var bob: Party
data class ScheduledState(val creationTime: Instant,
val source: Party,
@ -97,9 +98,11 @@ class ScheduledFlowTests {
@Before
fun setup() {
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.testing.contracts"))
nodeA = mockNet.createNode()
nodeB = mockNet.createNode()
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
notary = mockNet.defaultNotaryIdentity
alice = aliceNode.info.singleIdentity()
bob = bobNode.info.singleIdentity()
}
@After
@ -110,20 +113,20 @@ class ScheduledFlowTests {
@Test
fun `create and run scheduled flow then wait for result`() {
var countScheduledFlows = 0
nodeA.smm.track().updates.subscribe {
aliceNode.smm.track().updates.subscribe {
if (it is StateMachineManager.Change.Add) {
val context = it.logic.stateMachine.context
if (context.origin is Origin.Scheduled)
countScheduledFlows++
}
}
nodeA.services.startFlow(InsertInitialStateFlow(nodeB.info.chooseIdentity(), notary))
aliceNode.services.startFlow(InsertInitialStateFlow(bob, notary))
mockNet.waitQuiescent()
val stateFromA = nodeA.database.transaction {
nodeA.services.vaultService.queryBy<ScheduledState>().states.single()
val stateFromA = aliceNode.database.transaction {
aliceNode.services.vaultService.queryBy<ScheduledState>().states.single()
}
val stateFromB = nodeB.database.transaction {
nodeB.services.vaultService.queryBy<ScheduledState>().states.single()
val stateFromB = bobNode.database.transaction {
bobNode.services.vaultService.queryBy<ScheduledState>().states.single()
}
assertEquals(1, countScheduledFlows)
assertEquals("Must be same copy on both nodes", stateFromA, stateFromB)
@ -135,8 +138,8 @@ class ScheduledFlowTests {
val N = 100
val futures = mutableListOf<CordaFuture<*>>()
for (i in 0 until N) {
futures.add(nodeA.services.startFlow(InsertInitialStateFlow(nodeB.info.chooseIdentity(), notary)).resultFuture)
futures.add(nodeB.services.startFlow(InsertInitialStateFlow(nodeA.info.chooseIdentity(), notary)).resultFuture)
futures.add(aliceNode.services.startFlow(InsertInitialStateFlow(bob, notary)).resultFuture)
futures.add(bobNode.services.startFlow(InsertInitialStateFlow(alice, notary)).resultFuture)
}
mockNet.waitQuiescent()
@ -144,11 +147,11 @@ class ScheduledFlowTests {
futures.forEach { it.getOrThrow() }
// Convert the states into maps to make error reporting easier
val statesFromA: List<StateAndRef<ScheduledState>> = nodeA.database.transaction {
queryStatesWithPaging(nodeA.services.vaultService)
val statesFromA: List<StateAndRef<ScheduledState>> = aliceNode.database.transaction {
queryStatesWithPaging(aliceNode.services.vaultService)
}
val statesFromB: List<StateAndRef<ScheduledState>> = nodeB.database.transaction {
queryStatesWithPaging(nodeB.services.vaultService)
val statesFromB: List<StateAndRef<ScheduledState>> = bobNode.database.transaction {
queryStatesWithPaging(bobNode.services.vaultService)
}
assertEquals("Expect all states to be present", 2 * N, statesFromA.count())
statesFromA.forEach { ref ->

View File

@ -1,11 +1,12 @@
package net.corda.node.services.network
import net.corda.core.node.services.NetworkMapCache
import net.corda.testing.ALICE
import net.corda.testing.BOB
import net.corda.testing.chooseIdentity
import net.corda.testing.ALICE_NAME
import net.corda.testing.BOB_NAME
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.singleIdentity
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Test
@ -23,26 +24,29 @@ class NetworkMapCacheTest {
@Test
fun `key collision`() {
val entropy = BigInteger.valueOf(24012017L)
val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE.name, entropyRoot = entropy))
val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME, entropyRoot = entropy))
val alice = aliceNode.info.singleIdentity()
// Node A currently knows only about itself, so this returns node A
assertEquals(aliceNode.services.networkMapCache.getNodesByLegalIdentityKey(aliceNode.info.chooseIdentity().owningKey).singleOrNull(), aliceNode.info)
val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB.name, entropyRoot = entropy))
assertEquals(aliceNode.info.chooseIdentity(), bobNode.info.chooseIdentity())
assertEquals(aliceNode.services.networkMapCache.getNodesByLegalIdentityKey(alice.owningKey).singleOrNull(), aliceNode.info)
val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME, entropyRoot = entropy))
val bob = bobNode.info.singleIdentity()
assertEquals(alice, bob)
aliceNode.services.networkMapCache.addNode(bobNode.info)
// The details of node B write over those for node A
assertEquals(aliceNode.services.networkMapCache.getNodesByLegalIdentityKey(aliceNode.info.chooseIdentity().owningKey).singleOrNull(), bobNode.info)
assertEquals(aliceNode.services.networkMapCache.getNodesByLegalIdentityKey(alice.owningKey).singleOrNull(), bobNode.info)
}
@Test
fun `getNodeByLegalIdentity`() {
val aliceNode = mockNet.createPartyNode(ALICE.name)
val bobNode = mockNet.createPartyNode(BOB.name)
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
val alice = aliceNode.info.singleIdentity()
val bobNode = mockNet.createPartyNode(BOB_NAME)
val bobCache: NetworkMapCache = bobNode.services.networkMapCache
val expected = aliceNode.info
val actual = bobNode.database.transaction { bobCache.getNodeByLegalIdentity(aliceNode.info.chooseIdentity()) }
val actual = bobNode.database.transaction { bobCache.getNodeByLegalIdentity(alice) }
assertEquals(expected, actual)
// TODO: Should have a test case with anonymous lookup
@ -50,27 +54,27 @@ class NetworkMapCacheTest {
@Test
fun `getPeerByLegalName`() {
val aliceNode = mockNet.createPartyNode(ALICE.name)
val bobNode = mockNet.createPartyNode(BOB.name)
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
val bobNode = mockNet.createPartyNode(BOB_NAME)
val bobCache: NetworkMapCache = bobNode.services.networkMapCache
val expected = aliceNode.info.legalIdentities.single()
val expected = aliceNode.info.singleIdentity()
val actual = bobNode.database.transaction { bobCache.getPeerByLegalName(ALICE.name) }
val actual = bobNode.database.transaction { bobCache.getPeerByLegalName(ALICE_NAME) }
assertEquals(expected, actual)
}
@Test
fun `remove node from cache`() {
val aliceNode = mockNet.createPartyNode(ALICE.name)
val bobNode = mockNet.createPartyNode(BOB.name)
val bobLegalIdentity = bobNode.info.chooseIdentity()
val alice = aliceNode.info.chooseIdentity()
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
val bobNode = mockNet.createPartyNode(BOB_NAME)
val bob = bobNode.info.singleIdentity()
val alice = aliceNode.info.singleIdentity()
val bobCache = bobNode.services.networkMapCache
bobNode.database.transaction {
assertThat(bobCache.getNodeByLegalIdentity(alice) != null)
bobCache.removeNode(aliceNode.info)
assertThat(bobCache.getNodeByLegalIdentity(alice) == null)
assertThat(bobCache.getNodeByLegalIdentity(bobLegalIdentity) != null)
assertThat(bobCache.getNodeByLegalIdentity(bob) != null)
assertThat(bobCache.getNodeByLegalName(alice.name) == null)
}
}

View File

@ -9,6 +9,7 @@ import net.corda.core.crypto.*
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.packageName
import net.corda.core.node.StatesToRecord
import net.corda.core.node.services.StatesNotAvailableException
@ -59,11 +60,12 @@ class NodeVaultServiceTest {
@Rule
@JvmField
val testSerialization = SerializationEnvironmentRule()
lateinit var services: MockServices
private lateinit var services: MockServices
private lateinit var identity: PartyAndCertificate
private lateinit var issuerServices: MockServices
private lateinit var bocServices: MockServices
val vaultService get() = services.vaultService as NodeVaultService
lateinit var database: CordaPersistence
private val vaultService get() = services.vaultService as NodeVaultService
private lateinit var database: CordaPersistence
@Before
fun setUp() {
@ -71,6 +73,8 @@ class NodeVaultServiceTest {
val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(cordappPackages = cordappPackages)
database = databaseAndServices.first
services = databaseAndServices.second
// This is safe because MockServices only ever have a single identity
identity = services.myInfo.singleIdentityAndCert()
issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_NAME, DUMMY_CASH_ISSUER_KEY)
bocServices = MockServices(cordappPackages, BOC_NAME, BOC_KEY)
services.identityService.verifyAndRegisterIdentity(DUMMY_CASH_ISSUER_IDENTITY)
@ -456,7 +460,7 @@ class NodeVaultServiceTest {
fun addNoteToTransaction() {
val megaCorpServices = MockServices(cordappPackages, MEGA_CORP.name, MEGA_CORP_KEY)
database.transaction {
val freshKey = services.myInfo.chooseIdentity().owningKey
val freshKey = identity.owningKey
// Issue a txn to Send us some Money
val usefulBuilder = TransactionBuilder(null).apply {
@ -488,11 +492,11 @@ class NodeVaultServiceTest {
fun `is ownable state relevant`() {
val service = vaultService
val amount = Amount(1000, Issued(BOC.ref(1), GBP))
val wellKnownCash = Cash.State(amount, services.myInfo.chooseIdentity())
val wellKnownCash = Cash.State(amount, identity.party)
val myKeys = services.keyManagementService.filterMyKeys(listOf(wellKnownCash.owner.owningKey))
assertTrue { service.isRelevant(wellKnownCash, myKeys.toSet()) }
val anonymousIdentity = services.keyManagementService.freshKeyAndCert(services.myInfo.chooseIdentityAndCert(), false)
val anonymousIdentity = services.keyManagementService.freshKeyAndCert(identity, false)
val anonymousCash = Cash.State(amount, anonymousIdentity.party)
val anonymousKeys = services.keyManagementService.filterMyKeys(listOf(anonymousCash.owner.owningKey))
assertTrue { service.isRelevant(anonymousCash, anonymousKeys.toSet()) }
@ -508,6 +512,7 @@ class NodeVaultServiceTest {
@Test
fun `correct updates are generated for general transactions`() {
val service = vaultService
val notary = identity.party
val vaultSubscriber = TestSubscriber<Vault.Update<*>>().apply {
service.updates.subscribe(this)
}
@ -518,30 +523,30 @@ class NodeVaultServiceTest {
val amount = Amount(1000, Issued(BOC.ref(1), GBP))
// Issue then move some cash
val builder = TransactionBuilder(identity.party).apply {
val issueBuilder = TransactionBuilder(notary).apply {
Cash().generateIssue(this, amount, anonymousIdentity.party.anonymise(), identity.party)
}
val issueTx = builder.toWireTransaction(bocServices)
val issueTx = issueBuilder.toWireTransaction(bocServices)
val cashState = StateAndRef(issueTx.outputs.single(), StateRef(issueTx.id, 0))
// ensure transaction contract state is persisted in DBStorage
val signedIssuedTx = services.signInitialTransaction(builder)
val signedIssuedTx = services.signInitialTransaction(issueBuilder)
services.validatedTransactions.addTransaction(signedIssuedTx)
database.transaction { service.notify(StatesToRecord.ONLY_RELEVANT, issueTx) }
val expectedIssueUpdate = Vault.Update(emptySet(), setOf(cashState), null)
database.transaction {
val builder = TransactionBuilder(services.myInfo.chooseIdentity()).apply {
val moveBuilder = TransactionBuilder(notary).apply {
Cash.generateSpend(services, this, Amount(1000, GBP), thirdPartyIdentity)
}
val moveTx = builder.toWireTransaction(services)
val moveTx = moveBuilder.toWireTransaction(services)
service.notify(StatesToRecord.ONLY_RELEVANT, moveTx)
}
val expectedMoveUpdate = Vault.Update(setOf(cashState), emptySet(), null)
// ensure transaction contract state is persisted in DBStorage
val signedMoveTx = services.signInitialTransaction(builder)
val signedMoveTx = services.signInitialTransaction(issueBuilder)
services.validatedTransactions.addTransaction(signedMoveTx)
val observedUpdates = vaultSubscriber.onNextEvents
@ -551,7 +556,7 @@ class NodeVaultServiceTest {
@Test
fun `correct updates are generated when changing notaries`() {
val service = vaultService
val notary = services.myInfo.chooseIdentity()
val notary = identity.party
val vaultSubscriber = TestSubscriber<Vault.Update<*>>().apply {
service.updates.subscribe(this)

View File

@ -6,6 +6,7 @@ import net.corda.core.contracts.LinearState
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party
import net.corda.core.internal.concurrent.fork
import net.corda.core.internal.concurrent.transpose
import net.corda.core.internal.packageName
@ -53,7 +54,8 @@ class VaultWithCashTest {
lateinit var issuerServices: MockServices
val vaultService: VaultService get() = services.vaultService
lateinit var database: CordaPersistence
lateinit var notaryServices: MockServices
private lateinit var notaryServices: MockServices
private lateinit var notary: Party
@Before
fun setUp() {
@ -63,6 +65,7 @@ class VaultWithCashTest {
services = databaseAndServices.second
issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_NAME, DUMMY_CASH_ISSUER_KEY, MEGA_CORP_KEY)
notaryServices = MockServices(cordappPackages, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
notary = notaryServices.myInfo.legalIdentitiesAndCerts.single().party
}
@After
@ -237,10 +240,10 @@ class VaultWithCashTest {
val linearId = UniqueIdentifier()
// Issue a linear state
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY).apply {
val dummyIssueBuilder = TransactionBuilder(notary = notary).apply {
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey))
addCommand(dummyCommand(notary!!.owningKey))
}
val dummyIssue = notaryServices.signInitialTransaction(dummyIssueBuilder)
@ -261,7 +264,7 @@ class VaultWithCashTest {
// Issue a linear state
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
.addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
.addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey))
.addCommand(dummyCommand(notary.owningKey))
val dummyIssuePtx = notaryServices.signInitialTransaction(dummyIssueBuilder)
val dummyIssue = services.addSignature(dummyIssuePtx)
@ -277,7 +280,7 @@ class VaultWithCashTest {
val dummyMoveBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
.addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
.addInputState(dummyIssue.tx.outRef<LinearState>(0))
.addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey))
.addCommand(dummyCommand(notary.owningKey))
val dummyMove = notaryServices.signInitialTransaction(dummyMoveBuilder)
@ -348,12 +351,12 @@ class VaultWithCashTest {
linearStates.forEach { println(it.state.data.linearId) }
// Create a txn consuming different contract types
val dummyMoveBuilder = TransactionBuilder(notary = DUMMY_NOTARY).apply {
val dummyMoveBuilder = TransactionBuilder(notary = notary).apply {
addOutputState(DummyLinearContract.State(participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
addOutputState(DummyDealContract.State(ref = "999", participants = listOf(freshIdentity)), DUMMY_DEAL_PROGRAM_ID)
addInputState(linearStates.first())
addInputState(deals.first())
addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey))
addCommand(dummyCommand(notary!!.owningKey))
}
val dummyMove = notaryServices.signInitialTransaction(dummyMoveBuilder)