mirror of
https://github.com/corda/corda.git
synced 2025-06-16 14:18:20 +00:00
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:
@ -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))
|
||||
},
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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 ->
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Reference in New Issue
Block a user