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

@ -64,7 +64,7 @@ class NodeMonitorModelTest {
invokeRpc(CordaRPCOps::stateMachinesFeed), invokeRpc(CordaRPCOps::stateMachinesFeed),
invokeRpc(CordaRPCOps::networkMapFeed)) invokeRpc(CordaRPCOps::networkMapFeed))
) )
val aliceNodeHandle = startNode(providedName = ALICE.name, rpcUsers = listOf(cashUser)).getOrThrow() val aliceNodeHandle = startNode(providedName = ALICE_NAME, rpcUsers = listOf(cashUser)).getOrThrow()
aliceNode = aliceNodeHandle.nodeInfo aliceNode = aliceNodeHandle.nodeInfo
newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo } newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo }
val monitor = NodeMonitorModel() val monitor = NodeMonitorModel()
@ -79,7 +79,7 @@ class NodeMonitorModelTest {
rpc = monitor.proxyObservable.value!! rpc = monitor.proxyObservable.value!!
notaryParty = defaultNotaryIdentity notaryParty = defaultNotaryIdentity
val bobNodeHandle = startNode(providedName = BOB.name, rpcUsers = listOf(cashUser)).getOrThrow() val bobNodeHandle = startNode(providedName = BOB_NAME, rpcUsers = listOf(cashUser)).getOrThrow()
bobNode = bobNodeHandle.nodeInfo bobNode = bobNodeHandle.nodeInfo
val monitorBob = NodeMonitorModel() val monitorBob = NodeMonitorModel()
stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed() stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed()
@ -91,20 +91,20 @@ class NodeMonitorModelTest {
@Test @Test
fun `network map update`() = setup { fun `network map update`() = setup {
val charlieNode = newNode(CHARLIE.name) val charlieNode = newNode(CHARLIE_NAME)
val nonServiceIdentities = aliceNode.legalIdentitiesAndCerts + bobNode.legalIdentitiesAndCerts + charlieNode.legalIdentitiesAndCerts val nonServiceIdentities = aliceNode.legalIdentitiesAndCerts + bobNode.legalIdentitiesAndCerts + charlieNode.legalIdentitiesAndCerts
networkMapUpdates.filter { it.node.legalIdentitiesAndCerts.any { it in nonServiceIdentities } } networkMapUpdates.filter { it.node.legalIdentitiesAndCerts.any { it in nonServiceIdentities } }
.expectEvents(isStrict = false) { .expectEvents(isStrict = false) {
sequence( sequence(
// TODO : Add test for remove when driver DSL support individual node shutdown. // TODO : Add test for remove when driver DSL support individual node shutdown.
expect { output: NetworkMapCache.MapChange -> expect { output: NetworkMapCache.MapChange ->
require(output.node.chooseIdentity().name == ALICE.name) { "Expecting : ${ALICE.name}, Actual : ${output.node.chooseIdentity().name}" } require(output.node.legalIdentities.any { it.name == ALICE_NAME }) { "Expecting : ${ALICE_NAME}, Actual : ${output.node.legalIdentities.map(Party::name)}" }
}, },
expect { output: NetworkMapCache.MapChange -> expect { output: NetworkMapCache.MapChange ->
require(output.node.chooseIdentity().name == BOB.name) { "Expecting : ${BOB.name}, Actual : ${output.node.chooseIdentity().name}" } require(output.node.legalIdentities.any { it.name == BOB_NAME }) { "Expecting : ${BOB_NAME}, Actual : ${output.node.legalIdentities.map(Party::name)}" }
}, },
expect { output: NetworkMapCache.MapChange -> expect { output: NetworkMapCache.MapChange ->
require(output.node.chooseIdentity().name == CHARLIE.name) { "Expecting : ${CHARLIE.name}, Actual : ${output.node.chooseIdentity().name}" } require(output.node.legalIdentities.any { it.name == CHARLIE_NAME }) { "Expecting : ${CHARLIE_NAME}, Actual : ${output.node.legalIdentities.map(Party::name)}" }
} }
) )
} }

View File

@ -2,6 +2,7 @@ package net.corda.client.rpc
import net.corda.core.context.* import net.corda.core.context.*
import net.corda.core.crypto.random63BitValue import net.corda.core.crypto.random63BitValue
import net.corda.core.identity.Party
import net.corda.core.internal.concurrent.flatMap import net.corda.core.internal.concurrent.flatMap
import net.corda.core.internal.packageName import net.corda.core.internal.packageName
import net.corda.core.messaging.* import net.corda.core.messaging.*
@ -28,7 +29,6 @@ import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import kotlin.reflect.KClass
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
@ -42,6 +42,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
invokeRpc("vaultQueryByCriteria")) invokeRpc("vaultQueryByCriteria"))
) )
private lateinit var node: StartedNode<Node> private lateinit var node: StartedNode<Node>
private lateinit var identity: Party
private lateinit var client: CordaRPCClient private lateinit var client: CordaRPCClient
private var connection: CordaRPCConnection? = null private var connection: CordaRPCConnection? = null
@ -51,8 +52,9 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
@Before @Before
fun setUp() { fun setUp() {
node = startNode(ALICE.name, rpcUsers = listOf(rpcUser)) node = startNode(ALICE_NAME, rpcUsers = listOf(rpcUser))
client = CordaRPCClient(node.internals.configuration.rpcAddress!!) client = CordaRPCClient(node.internals.configuration.rpcAddress!!)
identity = node.info.identityFromX500Name(ALICE_NAME)
} }
@After @After
@ -86,7 +88,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
println("Creating proxy") println("Creating proxy")
println("Starting flow") println("Starting flow")
val flowHandle = connection!!.proxy.startTrackedFlow(::CashIssueFlow, val flowHandle = connection!!.proxy.startTrackedFlow(::CashIssueFlow,
20.DOLLARS, OpaqueBytes.of(0), node.info.chooseIdentity() 20.DOLLARS, OpaqueBytes.of(0), identity
) )
println("Started flow, waiting on result") println("Started flow, waiting on result")
flowHandle.progress.subscribe { flowHandle.progress.subscribe {
@ -98,7 +100,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
@Test @Test
fun `sub-type of FlowException thrown by flow`() { fun `sub-type of FlowException thrown by flow`() {
login(rpcUser.username, rpcUser.password) login(rpcUser.username, rpcUser.password)
val handle = connection!!.proxy.startFlow(::CashPaymentFlow, 100.DOLLARS, node.info.chooseIdentity()) val handle = connection!!.proxy.startFlow(::CashPaymentFlow, 100.DOLLARS, identity)
assertThatExceptionOfType(CashException::class.java).isThrownBy { assertThatExceptionOfType(CashException::class.java).isThrownBy {
handle.returnValue.getOrThrow() handle.returnValue.getOrThrow()
} }
@ -107,7 +109,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
@Test @Test
fun `check basic flow has no progress`() { fun `check basic flow has no progress`() {
login(rpcUser.username, rpcUser.password) login(rpcUser.username, rpcUser.password)
connection!!.proxy.startFlow(::CashPaymentFlow, 100.DOLLARS, node.info.chooseIdentity()).use { connection!!.proxy.startFlow(::CashPaymentFlow, 100.DOLLARS, identity).use {
assertFalse(it is FlowProgressHandle<*>) assertFalse(it is FlowProgressHandle<*>)
} }
} }
@ -120,7 +122,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
assertTrue(startCash.isEmpty(), "Should not start with any cash") assertTrue(startCash.isEmpty(), "Should not start with any cash")
val flowHandle = proxy.startFlow(::CashIssueFlow, val flowHandle = proxy.startFlow(::CashIssueFlow,
123.DOLLARS, OpaqueBytes.of(0), node.info.chooseIdentity() 123.DOLLARS, OpaqueBytes.of(0), identity
) )
println("Started issuing cash, waiting on result") println("Started issuing cash, waiting on result")
flowHandle.returnValue.get() flowHandle.returnValue.get()
@ -136,13 +138,12 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
val impersonatedActor = Actor(Actor.Id("Mark Dadada"), AuthServiceId("Test"), owningLegalIdentity = BOB.name) val impersonatedActor = Actor(Actor.Id("Mark Dadada"), AuthServiceId("Test"), owningLegalIdentity = BOB.name)
login(rpcUser.username, rpcUser.password, externalTrace, impersonatedActor) login(rpcUser.username, rpcUser.password, externalTrace, impersonatedActor)
val proxy = connection!!.proxy val proxy = connection!!.proxy
val nodeIdentity = node.info.chooseIdentity()
val updates = proxy.stateMachinesFeed().updates val updates = proxy.stateMachinesFeed().updates
node.services.startFlow(CashIssueFlow(2000.DOLLARS, OpaqueBytes.of(0), nodeIdentity), InvocationContext.shell()).flatMap { it.resultFuture }.getOrThrow() node.services.startFlow(CashIssueFlow(2000.DOLLARS, OpaqueBytes.of(0),identity), InvocationContext.shell()).flatMap { it.resultFuture }.getOrThrow()
proxy.startFlow(::CashIssueFlow, 123.DOLLARS, OpaqueBytes.of(0), nodeIdentity).returnValue.getOrThrow() proxy.startFlow(::CashIssueFlow, 123.DOLLARS, OpaqueBytes.of(0), identity).returnValue.getOrThrow()
proxy.startFlowDynamic(CashIssueFlow::class.java, 1000.DOLLARS, OpaqueBytes.of(0), nodeIdentity).returnValue.getOrThrow() proxy.startFlowDynamic(CashIssueFlow::class.java, 1000.DOLLARS, OpaqueBytes.of(0), identity).returnValue.getOrThrow()
val historicalIds = mutableSetOf<Trace.InvocationId>() val historicalIds = mutableSetOf<Trace.InvocationId>()
var sessionId: Trace.SessionId? = null var sessionId: Trace.SessionId? = null

View File

@ -3,10 +3,12 @@ package net.corda.confidential
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import org.junit.Before import org.junit.Before
import net.corda.testing.node.MockNodeParameters
import org.junit.Test import org.junit.Test
import kotlin.test.* import kotlin.test.*
@ -83,28 +85,30 @@ class SwapIdentitiesFlowTests {
val notaryNode = mockNet.defaultNotaryNode val notaryNode = mockNet.defaultNotaryNode
val aliceNode = mockNet.createPartyNode(ALICE.name) val aliceNode = mockNet.createPartyNode(ALICE.name)
val bobNode = mockNet.createPartyNode(BOB.name) val bobNode = mockNet.createPartyNode(BOB.name)
val bob: Party = bobNode.services.myInfo.singleIdentity() val alice: PartyAndCertificate = aliceNode.info.singleIdentityAndCert()
val bob: PartyAndCertificate = bobNode.info.singleIdentityAndCert()
val notary: PartyAndCertificate = mockNet.defaultNotaryIdentityAndCert
// Check that the wrong signature is rejected // Check that the wrong signature is rejected
notaryNode.database.transaction { notaryNode.database.transaction {
notaryNode.services.keyManagementService.freshKeyAndCert(notaryNode.services.myInfo.chooseIdentityAndCert(), false) notaryNode.services.keyManagementService.freshKeyAndCert(notary, false)
}.let { anonymousNotary -> }.let { anonymousNotary ->
val sigData = SwapIdentitiesFlow.buildDataToSign(anonymousNotary) val sigData = SwapIdentitiesFlow.buildDataToSign(anonymousNotary)
val signature = notaryNode.services.keyManagementService.sign(sigData, anonymousNotary.owningKey) val signature = notaryNode.services.keyManagementService.sign(sigData, anonymousNotary.owningKey)
assertFailsWith<SwapIdentitiesException>("Signature does not match the given identity and nonce") { assertFailsWith<SwapIdentitiesException>("Signature does not match the given identity and nonce") {
SwapIdentitiesFlow.validateAndRegisterIdentity(aliceNode.services.identityService, bob, anonymousNotary, signature.withoutKey()) SwapIdentitiesFlow.validateAndRegisterIdentity(aliceNode.services.identityService, bob.party, anonymousNotary, signature.withoutKey())
} }
} }
// Check that the right signing key, but wrong identity is rejected // Check that the right signing key, but wrong identity is rejected
val anonymousAlice = aliceNode.database.transaction { val anonymousAlice: PartyAndCertificate = aliceNode.database.transaction {
aliceNode.services.keyManagementService.freshKeyAndCert(aliceNode.services.myInfo.chooseIdentityAndCert(), false) aliceNode.services.keyManagementService.freshKeyAndCert(alice, false)
} }
bobNode.database.transaction { bobNode.database.transaction {
bobNode.services.keyManagementService.freshKeyAndCert(bobNode.services.myInfo.chooseIdentityAndCert(), false) bobNode.services.keyManagementService.freshKeyAndCert(bob, false)
}.let { anonymousBob -> }.let { anonymousBob ->
val sigData = SwapIdentitiesFlow.buildDataToSign(anonymousAlice) val sigData = SwapIdentitiesFlow.buildDataToSign(anonymousAlice)
val signature = bobNode.services.keyManagementService.sign(sigData, anonymousBob.owningKey) val signature = bobNode.services.keyManagementService.sign(sigData, anonymousBob.owningKey)
assertFailsWith<SwapIdentitiesException>("Signature does not match the given identity and nonce.") { assertFailsWith<SwapIdentitiesException>("Signature does not match the given identity and nonce.") {
SwapIdentitiesFlow.validateAndRegisterIdentity(aliceNode.services.identityService, bob, anonymousBob, signature.withoutKey()) SwapIdentitiesFlow.validateAndRegisterIdentity(aliceNode.services.identityService, bob.party, anonymousBob, signature.withoutKey())
} }
} }

View File

@ -44,8 +44,21 @@ data class NodeInfo(val addresses: List<NetworkHostAndPort>,
/** Returns true if [party] is one of the identities of this node, else false. */ /** Returns true if [party] is one of the identities of this node, else false. */
fun isLegalIdentity(party: Party): Boolean = party in legalIdentities 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\"") * Get a legal identity of this node from the X.500 name. This is intended for use in cases where the node is
return identity.party * expected to have a matching identity, and will throw an exception if no match is found.
*
* @throws IllegalArgumentException if the node has no matching identity.
*/
fun identityFromX500Name(name: CordaX500Name): Party = identityAndCertFromX500Name(name).party
/**
* Get a legal identity and certificate of this node from the X.500 name. This is intended for use in cases where
* the node is expected to have a matching identity, and will throw an exception if no match is found.
*
* @throws IllegalArgumentException if the node has no matching identity.
*/
fun identityAndCertFromX500Name(name: CordaX500Name): PartyAndCertificate {
return legalIdentitiesAndCerts.singleOrNull { it.name == name } ?: throw IllegalArgumentException("Node does not have an identity \"$name\"")
} }
} }

View File

@ -4,8 +4,8 @@ import co.paralleluniverse.fibers.Suspendable;
import com.google.common.primitives.Primitives; import com.google.common.primitives.Primitives;
import net.corda.core.identity.Party; import net.corda.core.identity.Party;
import net.corda.node.internal.StartedNode; import net.corda.node.internal.StartedNode;
import net.corda.testing.node.MockNetwork;
import net.corda.testing.TestConstants; import net.corda.testing.TestConstants;
import net.corda.testing.node.MockNetwork;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -13,7 +13,7 @@ import org.junit.Test;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import static net.corda.testing.CoreTestUtils.chooseIdentity; import static net.corda.testing.CoreTestUtils.singleIdentity;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static net.corda.testing.NodeTestUtils.startFlow; import static net.corda.testing.NodeTestUtils.startFlow;
@ -22,11 +22,13 @@ public class FlowsInJavaTest {
private final MockNetwork mockNet = new MockNetwork(); private final MockNetwork mockNet = new MockNetwork();
private StartedNode<MockNetwork.MockNode> aliceNode; private StartedNode<MockNetwork.MockNode> aliceNode;
private StartedNode<MockNetwork.MockNode> bobNode; private StartedNode<MockNetwork.MockNode> bobNode;
private Party bob;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
aliceNode = mockNet.createPartyNode(TestConstants.getALICE().getName()); aliceNode = mockNet.createPartyNode(TestConstants.getALICE().getName());
bobNode = mockNet.createPartyNode(TestConstants.getBOB().getName()); bobNode = mockNet.createPartyNode(TestConstants.getBOB().getName());
bob = singleIdentity(bobNode.getInfo());
} }
@After @After
@ -37,7 +39,7 @@ public class FlowsInJavaTest {
@Test @Test
public void suspendableActionInsideUnwrap() throws Exception { public void suspendableActionInsideUnwrap() throws Exception {
bobNode.getInternals().registerInitiatedFlow(SendHelloAndThenReceive.class); bobNode.getInternals().registerInitiatedFlow(SendHelloAndThenReceive.class);
Future<String> result = startFlow(aliceNode.getServices(), new SendInUnwrapFlow(chooseIdentity(bobNode.getInfo()))).getResultFuture(); Future<String> result = startFlow(aliceNode.getServices(), new SendInUnwrapFlow(bob)).getResultFuture();
mockNet.runNetwork(); mockNet.runNetwork();
assertThat(result.get()).isEqualTo("Hello"); assertThat(result.get()).isEqualTo("Hello");
} }
@ -52,7 +54,7 @@ public class FlowsInJavaTest {
} }
private void primitiveReceiveTypeTest(Class<?> receiveType) throws InterruptedException { private void primitiveReceiveTypeTest(Class<?> receiveType) throws InterruptedException {
PrimitiveReceiveFlow flow = new PrimitiveReceiveFlow(chooseIdentity(bobNode.getInfo()), receiveType); PrimitiveReceiveFlow flow = new PrimitiveReceiveFlow(bob, receiveType);
Future<?> result = startFlow(aliceNode.getServices(), flow).getResultFuture(); Future<?> result = startFlow(aliceNode.getServices(), flow).getResultFuture();
mockNet.runNetwork(); mockNet.runNetwork();
try { try {

View File

@ -41,13 +41,20 @@ class ContractUpgradeFlowTest {
private lateinit var aliceNode: StartedNode<MockNetwork.MockNode> private lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
private lateinit var bobNode: StartedNode<MockNetwork.MockNode> private lateinit var bobNode: StartedNode<MockNetwork.MockNode>
private lateinit var notary: Party private lateinit var notary: Party
private lateinit var alice: Party
private lateinit var bob: Party
@Before @Before
fun setup() { fun setup() {
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows")) mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows"))
aliceNode = mockNet.createPartyNode(ALICE.name) aliceNode = mockNet.createPartyNode(ALICE_NAME)
bobNode = mockNet.createPartyNode(BOB.name) bobNode = mockNet.createPartyNode(BOB_NAME)
notary = mockNet.defaultNotaryIdentity notary = mockNet.defaultNotaryIdentity
alice = aliceNode.info.singleIdentity()
bob = bobNode.info.singleIdentity()
// Process registration
mockNet.runNetwork()
} }
@After @After
@ -58,11 +65,11 @@ class ContractUpgradeFlowTest {
@Test @Test
fun `2 parties contract upgrade`() { fun `2 parties contract upgrade`() {
// Create dummy contract. // Create dummy contract.
val twoPartyDummyContract = DummyContract.generateInitial(0, notary, aliceNode.info.chooseIdentity().ref(1), bobNode.info.chooseIdentity().ref(1)) val twoPartyDummyContract = DummyContract.generateInitial(0, notary, alice.ref(1), bob.ref(1))
val signedByA = aliceNode.services.signInitialTransaction(twoPartyDummyContract) val signedByA = aliceNode.services.signInitialTransaction(twoPartyDummyContract)
val stx = bobNode.services.addSignature(signedByA) val stx = bobNode.services.addSignature(signedByA)
aliceNode.services.startFlow(FinalityFlow(stx, setOf(bobNode.info.chooseIdentity()))) aliceNode.services.startFlow(FinalityFlow(stx, setOf(bob)))
mockNet.runNetwork() mockNet.runNetwork()
val atx = aliceNode.database.transaction { aliceNode.services.validatedTransactions.getTransaction(stx.id) } val atx = aliceNode.database.transaction { aliceNode.services.validatedTransactions.getTransaction(stx.id) }
@ -128,7 +135,7 @@ class ContractUpgradeFlowTest {
fun `2 parties contract upgrade using RPC`() { fun `2 parties contract upgrade using RPC`() {
rpcDriver(initialiseSerialization = false) { rpcDriver(initialiseSerialization = false) {
// Create dummy contract. // Create dummy contract.
val twoPartyDummyContract = DummyContract.generateInitial(0, notary, aliceNode.info.chooseIdentity().ref(1), bobNode.info.chooseIdentity().ref(1)) val twoPartyDummyContract = DummyContract.generateInitial(0, notary, alice.ref(1), bob.ref(1))
val signedByA = aliceNode.services.signInitialTransaction(twoPartyDummyContract) val signedByA = aliceNode.services.signInitialTransaction(twoPartyDummyContract)
val stx = bobNode.services.addSignature(signedByA) val stx = bobNode.services.addSignature(signedByA)
@ -140,7 +147,7 @@ class ContractUpgradeFlowTest {
)) ))
val rpcA = startProxy(aliceNode, user) val rpcA = startProxy(aliceNode, user)
val rpcB = startProxy(bobNode, user) val rpcB = startProxy(bobNode, user)
val handle = rpcA.startFlow(::FinalityInvoker, stx, setOf(bobNode.info.chooseIdentity())) val handle = rpcA.startFlow(::FinalityInvoker, stx, setOf(bob))
mockNet.runNetwork() mockNet.runNetwork()
handle.returnValue.getOrThrow() handle.returnValue.getOrThrow()
@ -202,7 +209,7 @@ class ContractUpgradeFlowTest {
@Test @Test
fun `upgrade Cash to v2`() { fun `upgrade Cash to v2`() {
// Create some cash. // Create some cash.
val chosenIdentity = aliceNode.info.chooseIdentity() val chosenIdentity = alice
val result = aliceNode.services.startFlow(CashIssueFlow(Amount(1000, USD), OpaqueBytes.of(1), notary)).resultFuture val result = aliceNode.services.startFlow(CashIssueFlow(Amount(1000, USD), OpaqueBytes.of(1), notary)).resultFuture
mockNet.runNetwork() mockNet.runNetwork()
val stx = result.getOrThrow().stx val stx = result.getOrThrow().stx

View File

@ -5,8 +5,8 @@ import net.corda.core.identity.Party
import net.corda.core.utilities.UntrustworthyData import net.corda.core.utilities.UntrustworthyData
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
import net.corda.testing.chooseIdentity
import net.corda.testing.node.network import net.corda.testing.node.network
import net.corda.testing.singleIdentity
import net.corda.testing.startFlow import net.corda.testing.startFlow
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Test import org.junit.Test
@ -20,7 +20,7 @@ class ReceiveMultipleFlowTests {
val stringValue = "Thriller" val stringValue = "Thriller"
nodes[2].registerAnswer(AlgorithmDefinition::class, stringValue) nodes[2].registerAnswer(AlgorithmDefinition::class, stringValue)
val flow = nodes[0].services.startFlow(ParallelAlgorithmMap(nodes[1].info.chooseIdentity(), nodes[2].info.chooseIdentity())) val flow = nodes[0].services.startFlow(ParallelAlgorithmMap(nodes[1].info.singleIdentity(), nodes[2].info.singleIdentity()))
runNetwork() runNetwork()
val result = flow.resultFuture.getOrThrow() val result = flow.resultFuture.getOrThrow()
@ -37,7 +37,7 @@ class ReceiveMultipleFlowTests {
val value2 = 6.0 val value2 = 6.0
nodes[2].registerAnswer(ParallelAlgorithmList::class, value2) nodes[2].registerAnswer(ParallelAlgorithmList::class, value2)
val flow = nodes[0].services.startFlow(ParallelAlgorithmList(nodes[1].info.chooseIdentity(), nodes[2].info.chooseIdentity())) val flow = nodes[0].services.startFlow(ParallelAlgorithmList(nodes[1].info.singleIdentity(), nodes[2].info.singleIdentity()))
runNetwork() runNetwork()
val data = flow.resultFuture.getOrThrow() val data = flow.resultFuture.getOrThrow()

View File

@ -10,9 +10,9 @@ import net.corda.core.utilities.sequence
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.MEGA_CORP import net.corda.testing.MEGA_CORP
import net.corda.testing.MINI_CORP import net.corda.testing.MINI_CORP
import net.corda.testing.chooseIdentity
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.singleIdentity
import net.corda.testing.startFlow import net.corda.testing.startFlow
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
@ -45,8 +45,8 @@ class ResolveTransactionsFlowTest {
megaCorpNode.internals.registerInitiatedFlow(TestResponseFlow::class.java) megaCorpNode.internals.registerInitiatedFlow(TestResponseFlow::class.java)
miniCorpNode.internals.registerInitiatedFlow(TestResponseFlow::class.java) miniCorpNode.internals.registerInitiatedFlow(TestResponseFlow::class.java)
notary = mockNet.defaultNotaryIdentity notary = mockNet.defaultNotaryIdentity
megaCorp = megaCorpNode.info.chooseIdentity() megaCorp = megaCorpNode.info.singleIdentity()
miniCorp = miniCorpNode.info.chooseIdentity() miniCorp = miniCorpNode.info.singleIdentity()
} }
@After @After

View File

@ -7,6 +7,7 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowSession import net.corda.core.flows.FlowSession
import net.corda.core.flows.InitiatingFlow import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.TestDataVendingFlow import net.corda.core.flows.TestDataVendingFlow
import net.corda.core.identity.Party
import net.corda.core.internal.FetchAttachmentsFlow import net.corda.core.internal.FetchAttachmentsFlow
import net.corda.core.internal.FetchDataFlow import net.corda.core.internal.FetchDataFlow
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
@ -15,9 +16,11 @@ import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.persistence.NodeAttachmentService import net.corda.node.services.persistence.NodeAttachmentService
import net.corda.node.utilities.currentDBSession import net.corda.node.utilities.currentDBSession
import net.corda.testing.chooseIdentity import net.corda.testing.ALICE_NAME
import net.corda.testing.BOB_NAME
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters import net.corda.testing.node.MockNodeParameters
import net.corda.testing.singleIdentity
import net.corda.testing.startFlow import net.corda.testing.startFlow
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
@ -63,13 +66,16 @@ class AttachmentSerializationTest {
private lateinit var mockNet: MockNetwork private lateinit var mockNet: MockNetwork
private lateinit var server: StartedNode<MockNetwork.MockNode> private lateinit var server: StartedNode<MockNetwork.MockNode>
private lateinit var client: StartedNode<MockNetwork.MockNode> private lateinit var client: StartedNode<MockNetwork.MockNode>
private lateinit var serverIdentity: Party
@Before @Before
fun setUp() { fun setUp() {
mockNet = MockNetwork() mockNet = MockNetwork()
server = mockNet.createNode() server = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
client = mockNet.createNode() client = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
client.internals.disableDBCloseOnStop() // Otherwise the in-memory database may disappear (taking the checkpoint with it) while we reboot the client. client.internals.disableDBCloseOnStop() // Otherwise the in-memory database may disappear (taking the checkpoint with it) while we reboot the client.
mockNet.runNetwork()
serverIdentity = server.info.singleIdentity()
} }
@After @After
@ -91,9 +97,7 @@ class AttachmentSerializationTest {
private class ClientResult(internal val attachmentContent: String) private class ClientResult(internal val attachmentContent: String)
@InitiatingFlow @InitiatingFlow
private abstract class ClientLogic(server: StartedNode<*>) : FlowLogic<ClientResult>() { private abstract class ClientLogic(val serverIdentity: Party) : FlowLogic<ClientResult>() {
internal val server = server.info.chooseIdentity()
@Suspendable @Suspendable
internal fun communicate(serverSession: FlowSession) { internal fun communicate(serverSession: FlowSession) {
serverSession.sendAndReceive<String>("ping one").unwrap { assertEquals("pong", it) } serverSession.sendAndReceive<String>("ping one").unwrap { assertEquals("pong", it) }
@ -112,30 +116,30 @@ class AttachmentSerializationTest {
override val signers get() = throw UnsupportedOperationException() override val signers get() = throw UnsupportedOperationException()
} }
private class CustomAttachmentLogic(server: StartedNode<*>, private val attachmentId: SecureHash, private val customContent: String) : ClientLogic(server) { private class CustomAttachmentLogic(serverIdentity: Party, private val attachmentId: SecureHash, private val customContent: String) : ClientLogic(serverIdentity) {
@Suspendable @Suspendable
override fun getAttachmentContent(): String { override fun getAttachmentContent(): String {
val customAttachment = CustomAttachment(attachmentId, customContent) val customAttachment = CustomAttachment(attachmentId, customContent)
val session = initiateFlow(server) val session = initiateFlow(serverIdentity)
communicate(session) communicate(session)
return customAttachment.customContent return customAttachment.customContent
} }
} }
private class OpenAttachmentLogic(server: StartedNode<*>, private val attachmentId: SecureHash) : ClientLogic(server) { private class OpenAttachmentLogic(serverIdentity: Party, private val attachmentId: SecureHash) : ClientLogic(serverIdentity) {
@Suspendable @Suspendable
override fun getAttachmentContent(): String { override fun getAttachmentContent(): String {
val localAttachment = serviceHub.attachments.openAttachment(attachmentId)!! val localAttachment = serviceHub.attachments.openAttachment(attachmentId)!!
val session = initiateFlow(server) val session = initiateFlow(serverIdentity)
communicate(session) communicate(session)
return localAttachment.extractContent() return localAttachment.extractContent()
} }
} }
private class FetchAttachmentLogic(server: StartedNode<*>, private val attachmentId: SecureHash) : ClientLogic(server) { private class FetchAttachmentLogic(serverIdentity: Party, private val attachmentId: SecureHash) : ClientLogic(serverIdentity) {
@Suspendable @Suspendable
override fun getAttachmentContent(): String { override fun getAttachmentContent(): String {
val serverSession = initiateFlow(server) val serverSession = initiateFlow(serverIdentity)
val (downloadedAttachment) = subFlow(FetchAttachmentsFlow(setOf(attachmentId), serverSession)).downloaded val (downloadedAttachment) = subFlow(FetchAttachmentsFlow(setOf(attachmentId), serverSession)).downloaded
serverSession.send(FetchDataFlow.Request.End) serverSession.send(FetchDataFlow.Request.End)
communicate(serverSession) communicate(serverSession)
@ -166,14 +170,14 @@ class AttachmentSerializationTest {
@Test @Test
fun `custom (and non-persisted) attachment should be saved in checkpoint`() { fun `custom (and non-persisted) attachment should be saved in checkpoint`() {
val attachmentId = SecureHash.sha256("any old data") val attachmentId = SecureHash.sha256("any old data")
launchFlow(CustomAttachmentLogic(server, attachmentId, "custom"), 1) launchFlow(CustomAttachmentLogic(serverIdentity, attachmentId, "custom"), 1)
assertEquals("custom", rebootClientAndGetAttachmentContent()) assertEquals("custom", rebootClientAndGetAttachmentContent())
} }
@Test @Test
fun `custom attachment should be saved in checkpoint even if its data was persisted`() { fun `custom attachment should be saved in checkpoint even if its data was persisted`() {
val attachmentId = client.saveAttachment("genuine") val attachmentId = client.saveAttachment("genuine")
launchFlow(CustomAttachmentLogic(server, attachmentId, "custom"), 1) launchFlow(CustomAttachmentLogic(serverIdentity, attachmentId, "custom"), 1)
client.hackAttachment(attachmentId, "hacked") // Should not be reloaded, checkAttachmentsOnLoad may cause next line to blow up if client attempts it. client.hackAttachment(attachmentId, "hacked") // Should not be reloaded, checkAttachmentsOnLoad may cause next line to blow up if client attempts it.
assertEquals("custom", rebootClientAndGetAttachmentContent()) assertEquals("custom", rebootClientAndGetAttachmentContent())
} }
@ -182,7 +186,7 @@ class AttachmentSerializationTest {
fun `only the hash of a regular attachment should be saved in checkpoint`() { fun `only the hash of a regular attachment should be saved in checkpoint`() {
val attachmentId = client.saveAttachment("genuine") val attachmentId = client.saveAttachment("genuine")
client.attachments.checkAttachmentsOnLoad = false // Cached by AttachmentImpl. client.attachments.checkAttachmentsOnLoad = false // Cached by AttachmentImpl.
launchFlow(OpenAttachmentLogic(server, attachmentId), 1) launchFlow(OpenAttachmentLogic(serverIdentity, attachmentId), 1)
client.hackAttachment(attachmentId, "hacked") client.hackAttachment(attachmentId, "hacked")
assertEquals("hacked", rebootClientAndGetAttachmentContent(false)) // Pass in false to allow non-genuine data to be loaded. assertEquals("hacked", rebootClientAndGetAttachmentContent(false)) // Pass in false to allow non-genuine data to be loaded.
} }
@ -190,7 +194,7 @@ class AttachmentSerializationTest {
@Test @Test
fun `only the hash of a FetchAttachmentsFlow attachment should be saved in checkpoint`() { fun `only the hash of a FetchAttachmentsFlow attachment should be saved in checkpoint`() {
val attachmentId = server.saveAttachment("genuine") val attachmentId = server.saveAttachment("genuine")
launchFlow(FetchAttachmentLogic(server, attachmentId), 2, sendData = true) launchFlow(FetchAttachmentLogic(serverIdentity, attachmentId), 2, sendData = true)
client.hackAttachment(attachmentId, "hacked") client.hackAttachment(attachmentId, "hacked")
assertEquals("hacked", rebootClientAndGetAttachmentContent(false)) assertEquals("hacked", rebootClientAndGetAttachmentContent(false))
} }

View File

@ -2,9 +2,13 @@ package net.corda.core.transactions
import net.corda.core.contracts.* import net.corda.core.contracts.*
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.testing.* import net.corda.core.identity.Party
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.SerializationEnvironmentRule
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.singleIdentity
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -18,6 +22,7 @@ class LedgerTransactionQueryTests {
@JvmField @JvmField
val testSerialization = SerializationEnvironmentRule() val testSerialization = SerializationEnvironmentRule()
private val services: MockServices = MockServices() private val services: MockServices = MockServices()
private val identity: Party = services.myInfo.singleIdentity()
@Before @Before
fun setup() { fun setup() {
@ -66,8 +71,8 @@ class LedgerTransactionQueryTests {
tx.addInputState(makeDummyStateAndRef(i.toString())) tx.addInputState(makeDummyStateAndRef(i.toString()))
tx.addOutputState(makeDummyState(i), DummyContract.PROGRAM_ID) tx.addOutputState(makeDummyState(i), DummyContract.PROGRAM_ID)
tx.addOutputState(makeDummyState(i.toString()), DummyContract.PROGRAM_ID) tx.addOutputState(makeDummyState(i.toString()), DummyContract.PROGRAM_ID)
tx.addCommand(Commands.Cmd1(i), listOf(services.myInfo.chooseIdentity().owningKey)) tx.addCommand(Commands.Cmd1(i), listOf(identity.owningKey))
tx.addCommand(Commands.Cmd2(i), listOf(services.myInfo.chooseIdentity().owningKey)) tx.addCommand(Commands.Cmd2(i), listOf(identity.owningKey))
} }
return tx.toLedgerTransaction(services) return tx.toLedgerTransaction(services)
} }

View File

@ -7,8 +7,7 @@ import net.corda.finance.DOLLARS
import net.corda.finance.`issued by` import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.BOC import net.corda.testing.BOC_NAME
import net.corda.testing.chooseIdentity
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode import net.corda.testing.node.MockNetwork.MockNode
@ -31,8 +30,8 @@ class CashExitFlowTests {
fun start() { fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("net.corda.finance.contracts.asset")) cordappPackages = listOf("net.corda.finance.contracts.asset"))
bankOfCordaNode = mockNet.createPartyNode(BOC.name) bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.chooseIdentity() bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
notary = mockNet.defaultNotaryIdentity notary = mockNet.defaultNotaryIdentity
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture
mockNet.runNetwork() mockNet.runNetwork()

View File

@ -7,8 +7,7 @@ import net.corda.finance.DOLLARS
import net.corda.finance.`issued by` import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.BOC import net.corda.testing.BOC_NAME
import net.corda.testing.chooseIdentity
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode import net.corda.testing.node.MockNetwork.MockNode
@ -28,8 +27,8 @@ class CashIssueFlowTests {
@Before @Before
fun start() { fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset")) mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset"))
bankOfCordaNode = mockNet.createPartyNode(BOC.name) bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.chooseIdentity() bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
notary = mockNet.defaultNotaryIdentity notary = mockNet.defaultNotaryIdentity
} }

View File

@ -31,9 +31,9 @@ class CashPaymentFlowTests {
@Before @Before
fun start() { fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset")) mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset"))
bankOfCordaNode = mockNet.createPartyNode(BOC.name) bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
aliceNode = mockNet.createPartyNode(ALICE.name) bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.chooseIdentity() aliceNode = mockNet.createPartyNode(ALICE_NAME)
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, mockNet.defaultNotaryIdentity)).resultFuture val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, mockNet.defaultNotaryIdentity)).resultFuture
future.getOrThrow() future.getOrThrow()
} }

View File

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

View File

@ -97,6 +97,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val bankNode = mockNet.createPartyNode(BOC_NAME) val bankNode = mockNet.createPartyNode(BOC_NAME)
val alice = aliceNode.info.singleIdentity() val alice = aliceNode.info.singleIdentity()
val bank = bankNode.info.singleIdentity() val bank = bankNode.info.singleIdentity()
val bob = bobNode.info.singleIdentity()
val notary = mockNet.defaultNotaryIdentity val notary = mockNet.defaultNotaryIdentity
val cashIssuer = bank.ref(1) val cashIssuer = bank.ref(1)
val cpIssuer = bank.ref(1, 2, 3) 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 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()) "alice's paper".outputStateAndRef())
// TODO: Verify that the result was inserted into the transaction database. // 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 bankNode = mockNet.createPartyNode(BOC_NAME)
val alice = aliceNode.info.singleIdentity() val alice = aliceNode.info.singleIdentity()
val bank = bankNode.info.singleIdentity() val bank = bankNode.info.singleIdentity()
val bob = bobNode.info.singleIdentity()
val issuer = bank.ref(1) val issuer = bank.ref(1)
val notary = mockNet.defaultNotaryIdentity val notary = mockNet.defaultNotaryIdentity
@ -163,7 +165,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
1200.DOLLARS `issued by` bank.ref(0), null, notary).second 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() val cashLockId = UUID.randomUUID()
bobNode.database.transaction { 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()) "alice's paper".outputStateAndRef())
assertEquals(aliceResult.getOrThrow(), bobStateMachine.getOrThrow().resultFuture.getOrThrow()) assertEquals(aliceResult.getOrThrow(), bobStateMachine.getOrThrow().resultFuture.getOrThrow())
@ -210,6 +212,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val notary = mockNet.defaultNotaryIdentity val notary = mockNet.defaultNotaryIdentity
val alice = aliceNode.info.singleIdentity() val alice = aliceNode.info.singleIdentity()
val bank = bankNode.info.singleIdentity() val bank = bankNode.info.singleIdentity()
val bob = bobNode.info.singleIdentity()
val issuer = bank.ref(1, 2, 3) val issuer = bank.ref(1, 2, 3)
bobNode.database.transaction { bobNode.database.transaction {
@ -220,8 +223,8 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
fillUpForSeller(false, issuer, alice, fillUpForSeller(false, issuer, alice,
1200.DOLLARS `issued by` bank.ref(0), null, notary).second 1200.DOLLARS `issued by` bank.ref(0), null, notary).second
} }
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
val aliceFuture = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerResult 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. // 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: // 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 { val bobsFakeCash = bobNode.database.transaction {
fillUpForBuyer(false, issuer, AnonymousParty(bob.owningKey), notary) fillUpForBuyer(false, issuer, AnonymousParty(bob.owningKey), notary)
}.second }.second
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode) val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, bob, notaryNode, bankNode)
val alicesFakePaper = aliceNode.database.transaction { val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, issuer, alice, fillUpForSeller(false, issuer, alice,
1200.DOLLARS `issued by` bank.ref(0), attachmentID, notary).second 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 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() mockNet.runNetwork()
@ -420,6 +423,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val notary = mockNet.defaultNotaryIdentity val notary = mockNet.defaultNotaryIdentity
val alice: Party = aliceNode.info.singleIdentity() val alice: Party = aliceNode.info.singleIdentity()
val bank: Party = bankNode.info.singleIdentity() val bank: Party = bankNode.info.singleIdentity()
val bob = bobNode.info.singleIdentity()
val issuer = bank.ref(1, 2, 3) val issuer = bank.ref(1, 2, 3)
ledger(aliceNode.services) { ledger(aliceNode.services) {
@ -438,20 +442,20 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val bobsFakeCash = bobNode.database.transaction { val bobsFakeCash = bobNode.database.transaction {
fillUpForBuyer(false, issuer, AnonymousParty(bobsKey), notary) fillUpForBuyer(false, issuer, AnonymousParty(bobsKey), notary)
}.second }.second
insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode) insertFakeTransactions(bobsFakeCash, bobNode, bob, notaryNode, bankNode)
val alicesFakePaper = aliceNode.database.transaction { val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, issuer, alice, fillUpForSeller(false, issuer, alice,
1200.DOLLARS `issued by` bank.ref(0), attachmentID, notary).second 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 aliceTxStream = aliceNode.services.validatedTransactions.track().updates
val aliceTxMappings = with(aliceNode) { val aliceTxMappings = with(aliceNode) {
database.transaction { services.stateMachineRecordedTransactionMapping.track().updates } database.transaction { services.stateMachineRecordedTransactionMapping.track().updates }
} }
val aliceSmId = runBuyerAndSeller(notary, aliceNode, bobNode, val aliceSmId = runBuyerAndSeller(notary, bob, aliceNode, bobNode,
"alice's paper".outputStateAndRef()).sellerId "alice's paper".outputStateAndRef()).sellerId
mockNet.runNetwork() mockNet.runNetwork()
@ -511,12 +515,13 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
) )
private fun runBuyerAndSeller(notary: Party, private fun runBuyerAndSeller(notary: Party,
buyer: Party,
sellerNode: StartedNode<MockNetwork.MockNode>, sellerNode: StartedNode<MockNetwork.MockNode>,
buyerNode: StartedNode<MockNetwork.MockNode>, buyerNode: StartedNode<MockNetwork.MockNode>,
assetToSell: StateAndRef<OwnableState>): RunResult { assetToSell: StateAndRef<OwnableState>): RunResult {
val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.internals.registerInitiatedFlow(BuyerAcceptor::class.java) val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.internals.registerInitiatedFlow(BuyerAcceptor::class.java)
val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine } 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 val sellerResult = sellerNode.services.startFlow(seller).resultFuture
return RunResult(firstBuyerFiber, sellerResult, seller.stateMachine.id) 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 fillUpForSeller(aliceError, issuer, alice,1200.DOLLARS `issued by` issuer, null, notary).second
} }
insertFakeTransactions(bobsBadCash, bobNode, notaryNode, bankNode) insertFakeTransactions(bobsBadCash, bobNode, bob, notaryNode, bankNode)
insertFakeTransactions(alicesFakePaper, aliceNode, 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() mockNet.runNetwork()
@ -605,13 +610,14 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
private fun insertFakeTransactions( private fun insertFakeTransactions(
wtxToSign: List<WireTransaction>, wtxToSign: List<WireTransaction>,
node: StartedNode<*>, node: StartedNode<*>,
identity: Party,
notaryNode: StartedNode<*>, notaryNode: StartedNode<*>,
vararg extraSigningNodes: StartedNode<*>): Map<SecureHash, SignedTransaction> { vararg extraSigningNodes: StartedNode<*>): Map<SecureHash, SignedTransaction> {
val notaryParty = mockNet.defaultNotaryIdentity val notaryParty = mockNet.defaultNotaryIdentity
val signed = wtxToSign.map { val signed = wtxToSign.map {
val id = it.id val id = it.id
val sigs = mutableListOf<TransactionSignature>() val sigs = mutableListOf<TransactionSignature>()
val nodeKey = node.info.chooseIdentity().owningKey val nodeKey = identity.owningKey
sigs += node.services.keyManagementService.sign( sigs += node.services.keyManagementService.sign(
SignableData(id, SignatureMetadata(1, Crypto.findSignatureScheme(nodeKey).schemeNumberID)), SignableData(id, SignatureMetadata(1, Crypto.findSignatureScheme(nodeKey).schemeNumberID)),
nodeKey nodeKey
@ -621,11 +627,12 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
notaryParty.owningKey notaryParty.owningKey
) )
extraSigningNodes.forEach { currentNode -> extraSigningNodes.forEach { currentNode ->
val currentIdentity = currentNode.info.singleIdentity()
sigs += currentNode.services.keyManagementService.sign( sigs += currentNode.services.keyManagementService.sign(
SignableData(id, SignatureMetadata( SignableData(id, SignatureMetadata(
1, 1,
Crypto.findSignatureScheme(currentNode.info.chooseIdentity().owningKey).schemeNumberID)), Crypto.findSignatureScheme(currentIdentity.owningKey).schemeNumberID)),
currentNode.info.chooseIdentity().owningKey) currentIdentity.owningKey)
} }
SignedTransaction(it, sigs) SignedTransaction(it, sigs)
} }

View File

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

View File

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

View File

@ -1,11 +1,12 @@
package net.corda.node.services.network package net.corda.node.services.network
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
import net.corda.testing.ALICE import net.corda.testing.ALICE_NAME
import net.corda.testing.BOB import net.corda.testing.BOB_NAME
import net.corda.testing.chooseIdentity import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters import net.corda.testing.node.MockNodeParameters
import net.corda.testing.singleIdentity
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.After import org.junit.After
import org.junit.Test import org.junit.Test
@ -23,26 +24,29 @@ class NetworkMapCacheTest {
@Test @Test
fun `key collision`() { fun `key collision`() {
val entropy = BigInteger.valueOf(24012017L) 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 // Node A currently knows only about itself, so this returns node A
assertEquals(aliceNode.services.networkMapCache.getNodesByLegalIdentityKey(aliceNode.info.chooseIdentity().owningKey).singleOrNull(), aliceNode.info) assertEquals(aliceNode.services.networkMapCache.getNodesByLegalIdentityKey(alice.owningKey).singleOrNull(), aliceNode.info)
val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB.name, entropyRoot = entropy)) val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME, entropyRoot = entropy))
assertEquals(aliceNode.info.chooseIdentity(), bobNode.info.chooseIdentity()) val bob = bobNode.info.singleIdentity()
assertEquals(alice, bob)
aliceNode.services.networkMapCache.addNode(bobNode.info) aliceNode.services.networkMapCache.addNode(bobNode.info)
// The details of node B write over those for node A // 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 @Test
fun `getNodeByLegalIdentity`() { fun `getNodeByLegalIdentity`() {
val aliceNode = mockNet.createPartyNode(ALICE.name) val aliceNode = mockNet.createPartyNode(ALICE_NAME)
val bobNode = mockNet.createPartyNode(BOB.name) val alice = aliceNode.info.singleIdentity()
val bobNode = mockNet.createPartyNode(BOB_NAME)
val bobCache: NetworkMapCache = bobNode.services.networkMapCache val bobCache: NetworkMapCache = bobNode.services.networkMapCache
val expected = aliceNode.info 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) assertEquals(expected, actual)
// TODO: Should have a test case with anonymous lookup // TODO: Should have a test case with anonymous lookup
@ -50,27 +54,27 @@ class NetworkMapCacheTest {
@Test @Test
fun `getPeerByLegalName`() { fun `getPeerByLegalName`() {
val aliceNode = mockNet.createPartyNode(ALICE.name) val aliceNode = mockNet.createPartyNode(ALICE_NAME)
val bobNode = mockNet.createPartyNode(BOB.name) val bobNode = mockNet.createPartyNode(BOB_NAME)
val bobCache: NetworkMapCache = bobNode.services.networkMapCache 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) assertEquals(expected, actual)
} }
@Test @Test
fun `remove node from cache`() { fun `remove node from cache`() {
val aliceNode = mockNet.createPartyNode(ALICE.name) val aliceNode = mockNet.createPartyNode(ALICE_NAME)
val bobNode = mockNet.createPartyNode(BOB.name) val bobNode = mockNet.createPartyNode(BOB_NAME)
val bobLegalIdentity = bobNode.info.chooseIdentity() val bob = bobNode.info.singleIdentity()
val alice = aliceNode.info.chooseIdentity() val alice = aliceNode.info.singleIdentity()
val bobCache = bobNode.services.networkMapCache val bobCache = bobNode.services.networkMapCache
bobNode.database.transaction { bobNode.database.transaction {
assertThat(bobCache.getNodeByLegalIdentity(alice) != null) assertThat(bobCache.getNodeByLegalIdentity(alice) != null)
bobCache.removeNode(aliceNode.info) bobCache.removeNode(aliceNode.info)
assertThat(bobCache.getNodeByLegalIdentity(alice) == null) assertThat(bobCache.getNodeByLegalIdentity(alice) == null)
assertThat(bobCache.getNodeByLegalIdentity(bobLegalIdentity) != null) assertThat(bobCache.getNodeByLegalIdentity(bob) != null)
assertThat(bobCache.getNodeByLegalName(alice.name) == 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.AbstractParty
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.packageName import net.corda.core.internal.packageName
import net.corda.core.node.StatesToRecord import net.corda.core.node.StatesToRecord
import net.corda.core.node.services.StatesNotAvailableException import net.corda.core.node.services.StatesNotAvailableException
@ -59,11 +60,12 @@ class NodeVaultServiceTest {
@Rule @Rule
@JvmField @JvmField
val testSerialization = SerializationEnvironmentRule() 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 issuerServices: MockServices
private lateinit var bocServices: MockServices private lateinit var bocServices: MockServices
val vaultService get() = services.vaultService as NodeVaultService private val vaultService get() = services.vaultService as NodeVaultService
lateinit var database: CordaPersistence private lateinit var database: CordaPersistence
@Before @Before
fun setUp() { fun setUp() {
@ -71,6 +73,8 @@ class NodeVaultServiceTest {
val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(cordappPackages = cordappPackages) val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(cordappPackages = cordappPackages)
database = databaseAndServices.first database = databaseAndServices.first
services = databaseAndServices.second 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) issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_NAME, DUMMY_CASH_ISSUER_KEY)
bocServices = MockServices(cordappPackages, BOC_NAME, BOC_KEY) bocServices = MockServices(cordappPackages, BOC_NAME, BOC_KEY)
services.identityService.verifyAndRegisterIdentity(DUMMY_CASH_ISSUER_IDENTITY) services.identityService.verifyAndRegisterIdentity(DUMMY_CASH_ISSUER_IDENTITY)
@ -456,7 +460,7 @@ class NodeVaultServiceTest {
fun addNoteToTransaction() { fun addNoteToTransaction() {
val megaCorpServices = MockServices(cordappPackages, MEGA_CORP.name, MEGA_CORP_KEY) val megaCorpServices = MockServices(cordappPackages, MEGA_CORP.name, MEGA_CORP_KEY)
database.transaction { database.transaction {
val freshKey = services.myInfo.chooseIdentity().owningKey val freshKey = identity.owningKey
// Issue a txn to Send us some Money // Issue a txn to Send us some Money
val usefulBuilder = TransactionBuilder(null).apply { val usefulBuilder = TransactionBuilder(null).apply {
@ -488,11 +492,11 @@ class NodeVaultServiceTest {
fun `is ownable state relevant`() { fun `is ownable state relevant`() {
val service = vaultService val service = vaultService
val amount = Amount(1000, Issued(BOC.ref(1), GBP)) 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)) val myKeys = services.keyManagementService.filterMyKeys(listOf(wellKnownCash.owner.owningKey))
assertTrue { service.isRelevant(wellKnownCash, myKeys.toSet()) } 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 anonymousCash = Cash.State(amount, anonymousIdentity.party)
val anonymousKeys = services.keyManagementService.filterMyKeys(listOf(anonymousCash.owner.owningKey)) val anonymousKeys = services.keyManagementService.filterMyKeys(listOf(anonymousCash.owner.owningKey))
assertTrue { service.isRelevant(anonymousCash, anonymousKeys.toSet()) } assertTrue { service.isRelevant(anonymousCash, anonymousKeys.toSet()) }
@ -508,6 +512,7 @@ class NodeVaultServiceTest {
@Test @Test
fun `correct updates are generated for general transactions`() { fun `correct updates are generated for general transactions`() {
val service = vaultService val service = vaultService
val notary = identity.party
val vaultSubscriber = TestSubscriber<Vault.Update<*>>().apply { val vaultSubscriber = TestSubscriber<Vault.Update<*>>().apply {
service.updates.subscribe(this) service.updates.subscribe(this)
} }
@ -518,30 +523,30 @@ class NodeVaultServiceTest {
val amount = Amount(1000, Issued(BOC.ref(1), GBP)) val amount = Amount(1000, Issued(BOC.ref(1), GBP))
// Issue then move some cash // 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) 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)) val cashState = StateAndRef(issueTx.outputs.single(), StateRef(issueTx.id, 0))
// ensure transaction contract state is persisted in DBStorage // ensure transaction contract state is persisted in DBStorage
val signedIssuedTx = services.signInitialTransaction(builder) val signedIssuedTx = services.signInitialTransaction(issueBuilder)
services.validatedTransactions.addTransaction(signedIssuedTx) services.validatedTransactions.addTransaction(signedIssuedTx)
database.transaction { service.notify(StatesToRecord.ONLY_RELEVANT, issueTx) } database.transaction { service.notify(StatesToRecord.ONLY_RELEVANT, issueTx) }
val expectedIssueUpdate = Vault.Update(emptySet(), setOf(cashState), null) val expectedIssueUpdate = Vault.Update(emptySet(), setOf(cashState), null)
database.transaction { database.transaction {
val builder = TransactionBuilder(services.myInfo.chooseIdentity()).apply { val moveBuilder = TransactionBuilder(notary).apply {
Cash.generateSpend(services, this, Amount(1000, GBP), thirdPartyIdentity) Cash.generateSpend(services, this, Amount(1000, GBP), thirdPartyIdentity)
} }
val moveTx = builder.toWireTransaction(services) val moveTx = moveBuilder.toWireTransaction(services)
service.notify(StatesToRecord.ONLY_RELEVANT, moveTx) service.notify(StatesToRecord.ONLY_RELEVANT, moveTx)
} }
val expectedMoveUpdate = Vault.Update(setOf(cashState), emptySet(), null) val expectedMoveUpdate = Vault.Update(setOf(cashState), emptySet(), null)
// ensure transaction contract state is persisted in DBStorage // ensure transaction contract state is persisted in DBStorage
val signedMoveTx = services.signInitialTransaction(builder) val signedMoveTx = services.signInitialTransaction(issueBuilder)
services.validatedTransactions.addTransaction(signedMoveTx) services.validatedTransactions.addTransaction(signedMoveTx)
val observedUpdates = vaultSubscriber.onNextEvents val observedUpdates = vaultSubscriber.onNextEvents
@ -551,7 +556,7 @@ class NodeVaultServiceTest {
@Test @Test
fun `correct updates are generated when changing notaries`() { fun `correct updates are generated when changing notaries`() {
val service = vaultService val service = vaultService
val notary = services.myInfo.chooseIdentity() val notary = identity.party
val vaultSubscriber = TestSubscriber<Vault.Update<*>>().apply { val vaultSubscriber = TestSubscriber<Vault.Update<*>>().apply {
service.updates.subscribe(this) 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.contracts.UniqueIdentifier
import net.corda.core.crypto.generateKeyPair import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.AnonymousParty 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.fork
import net.corda.core.internal.concurrent.transpose import net.corda.core.internal.concurrent.transpose
import net.corda.core.internal.packageName import net.corda.core.internal.packageName
@ -53,7 +54,8 @@ class VaultWithCashTest {
lateinit var issuerServices: MockServices lateinit var issuerServices: MockServices
val vaultService: VaultService get() = services.vaultService val vaultService: VaultService get() = services.vaultService
lateinit var database: CordaPersistence lateinit var database: CordaPersistence
lateinit var notaryServices: MockServices private lateinit var notaryServices: MockServices
private lateinit var notary: Party
@Before @Before
fun setUp() { fun setUp() {
@ -63,6 +65,7 @@ class VaultWithCashTest {
services = databaseAndServices.second services = databaseAndServices.second
issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_NAME, DUMMY_CASH_ISSUER_KEY, MEGA_CORP_KEY) issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_NAME, DUMMY_CASH_ISSUER_KEY, MEGA_CORP_KEY)
notaryServices = MockServices(cordappPackages, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) notaryServices = MockServices(cordappPackages, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
notary = notaryServices.myInfo.legalIdentitiesAndCerts.single().party
} }
@After @After
@ -237,10 +240,10 @@ class VaultWithCashTest {
val linearId = UniqueIdentifier() val linearId = UniqueIdentifier()
// Issue a linear state // 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)
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) val dummyIssue = notaryServices.signInitialTransaction(dummyIssueBuilder)
@ -261,7 +264,7 @@ class VaultWithCashTest {
// Issue a linear state // Issue a linear state
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY) val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
.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 dummyIssuePtx = notaryServices.signInitialTransaction(dummyIssueBuilder) val dummyIssuePtx = notaryServices.signInitialTransaction(dummyIssueBuilder)
val dummyIssue = services.addSignature(dummyIssuePtx) val dummyIssue = services.addSignature(dummyIssuePtx)
@ -277,7 +280,7 @@ class VaultWithCashTest {
val dummyMoveBuilder = TransactionBuilder(notary = DUMMY_NOTARY) val dummyMoveBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
.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)
.addInputState(dummyIssue.tx.outRef<LinearState>(0)) .addInputState(dummyIssue.tx.outRef<LinearState>(0))
.addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey)) .addCommand(dummyCommand(notary.owningKey))
val dummyMove = notaryServices.signInitialTransaction(dummyMoveBuilder) val dummyMove = notaryServices.signInitialTransaction(dummyMoveBuilder)
@ -348,12 +351,12 @@ class VaultWithCashTest {
linearStates.forEach { println(it.state.data.linearId) } linearStates.forEach { println(it.state.data.linearId) }
// Create a txn consuming different contract types // 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(DummyLinearContract.State(participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
addOutputState(DummyDealContract.State(ref = "999", participants = listOf(freshIdentity)), DUMMY_DEAL_PROGRAM_ID) addOutputState(DummyDealContract.State(ref = "999", participants = listOf(freshIdentity)), DUMMY_DEAL_PROGRAM_ID)
addInputState(linearStates.first()) addInputState(linearStates.first())
addInputState(deals.first()) addInputState(deals.first())
addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey)) addCommand(dummyCommand(notary!!.owningKey))
} }
val dummyMove = notaryServices.signInitialTransaction(dummyMoveBuilder) val dummyMove = notaryServices.signInitialTransaction(dummyMoveBuilder)

View File

@ -19,6 +19,7 @@ import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.configureDatabase import net.corda.node.utilities.configureDatabase
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseProperties import net.corda.testing.node.MockServices.Companion.makeTestDatabaseProperties
@ -51,13 +52,15 @@ class NodeInterestRatesTest {
private val DUMMY_CASH_ISSUER_KEY = generateKeyPair() private val DUMMY_CASH_ISSUER_KEY = generateKeyPair()
private val DUMMY_CASH_ISSUER = Party(CordaX500Name(organisation = "Cash issuer", locality = "London", country = "GB"), DUMMY_CASH_ISSUER_KEY.public) private val DUMMY_CASH_ISSUER = Party(CordaX500Name(organisation = "Cash issuer", locality = "London", country = "GB"), DUMMY_CASH_ISSUER_KEY.public)
private val services = MockServices(listOf("net.corda.finance.contracts.asset"), DUMMY_CASH_ISSUER.name, DUMMY_CASH_ISSUER_KEY, MEGA_CORP_KEY) private val services = MockServices(listOf("net.corda.finance.contracts.asset"), DUMMY_CASH_ISSUER.name, DUMMY_CASH_ISSUER_KEY, MEGA_CORP_KEY)
// This is safe because MockServices only ever have a single identity
private val identity = services.myInfo.singleIdentity()
private lateinit var oracle: NodeInterestRates.Oracle private lateinit var oracle: NodeInterestRates.Oracle
private lateinit var database: CordaPersistence private lateinit var database: CordaPersistence
private fun fixCmdFilter(elem: Any): Boolean { private fun fixCmdFilter(elem: Any): Boolean {
return when (elem) { return when (elem) {
is Command<*> -> services.myInfo.chooseIdentity().owningKey in elem.signers && elem.value is Fix is Command<*> -> identity.owningKey in elem.signers && elem.value is Fix
else -> false else -> false
} }
} }
@ -152,7 +155,7 @@ class NodeInterestRatesTest {
database.transaction { database.transaction {
val tx = makePartialTX() val tx = makePartialTX()
val fix = oracle.query(listOf(NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M"))).first() val fix = oracle.query(listOf(NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M"))).first()
tx.addCommand(fix, services.myInfo.chooseIdentity().owningKey) tx.addCommand(fix, identity.owningKey)
// Sign successfully. // Sign successfully.
val wtx = tx.toWireTransaction(services) val wtx = tx.toWireTransaction(services)
val ftx = wtx.buildFilteredTransaction(Predicate { fixCmdFilter(it) }) val ftx = wtx.buildFilteredTransaction(Predicate { fixCmdFilter(it) })
@ -167,7 +170,7 @@ class NodeInterestRatesTest {
val tx = makePartialTX() val tx = makePartialTX()
val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M") val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M")
val badFix = Fix(fixOf, BigDecimal("0.6789")) val badFix = Fix(fixOf, BigDecimal("0.6789"))
tx.addCommand(badFix, services.myInfo.chooseIdentity().owningKey) tx.addCommand(badFix, identity.owningKey)
val wtx = tx.toWireTransaction(services) val wtx = tx.toWireTransaction(services)
val ftx = wtx.buildFilteredTransaction(Predicate { fixCmdFilter(it) }) val ftx = wtx.buildFilteredTransaction(Predicate { fixCmdFilter(it) })
val e1 = assertFailsWith<NodeInterestRates.UnknownFix> { oracle.sign(ftx) } val e1 = assertFailsWith<NodeInterestRates.UnknownFix> { oracle.sign(ftx) }
@ -182,12 +185,12 @@ class NodeInterestRatesTest {
val fix = oracle.query(listOf(NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M"))).first() val fix = oracle.query(listOf(NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M"))).first()
fun filtering(elem: Any): Boolean { fun filtering(elem: Any): Boolean {
return when (elem) { return when (elem) {
is Command<*> -> services.myInfo.chooseIdentity().owningKey in elem.signers && elem.value is Fix is Command<*> -> identity.owningKey in elem.signers && elem.value is Fix
is TransactionState<ContractState> -> true is TransactionState<ContractState> -> true
else -> false else -> false
} }
} }
tx.addCommand(fix, services.myInfo.chooseIdentity().owningKey) tx.addCommand(fix, identity.owningKey)
val wtx = tx.toWireTransaction(services) val wtx = tx.toWireTransaction(services)
val ftx = wtx.buildFilteredTransaction(Predicate(::filtering)) val ftx = wtx.buildFilteredTransaction(Predicate(::filtering))
assertFailsWith<IllegalArgumentException> { oracle.sign(ftx) } assertFailsWith<IllegalArgumentException> { oracle.sign(ftx) }
@ -205,17 +208,18 @@ class NodeInterestRatesTest {
@Test @Test
fun `network tearoff`() = withoutTestSerialization { fun `network tearoff`() = withoutTestSerialization {
val mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts", "net.corda.irs")) val mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts", "net.corda.irs"))
val aliceNode = mockNet.createPartyNode(ALICE.name) val aliceNode = mockNet.createPartyNode(ALICE_NAME)
val oracleNode = mockNet.createNode().apply { val oracleNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME)).apply {
internals.registerInitiatedFlow(NodeInterestRates.FixQueryHandler::class.java) internals.registerInitiatedFlow(NodeInterestRates.FixQueryHandler::class.java)
internals.registerInitiatedFlow(NodeInterestRates.FixSignHandler::class.java) internals.registerInitiatedFlow(NodeInterestRates.FixSignHandler::class.java)
database.transaction { database.transaction {
services.cordaService(NodeInterestRates.Oracle::class.java).knownFixes = TEST_DATA services.cordaService(NodeInterestRates.Oracle::class.java).knownFixes = TEST_DATA
} }
} }
val oracle = oracleNode.services.myInfo.singleIdentity()
val tx = makePartialTX() val tx = makePartialTX()
val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M") val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M")
val flow = FilteredRatesFlow(tx, oracleNode.info.chooseIdentity(), fixOf, BigDecimal("0.675"), BigDecimal("0.1")) val flow = FilteredRatesFlow(tx, oracle, fixOf, BigDecimal("0.675"), BigDecimal("0.1"))
LogHelper.setLevel("rates") LogHelper.setLevel("rates")
mockNet.runNetwork() mockNet.runNetwork()
val future = aliceNode.services.startFlow(flow).resultFuture val future = aliceNode.services.startFlow(flow).resultFuture

View File

@ -8,6 +8,7 @@ import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.crypto.random63BitValue import net.corda.core.crypto.random63BitValue
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.createDirectories import net.corda.core.internal.createDirectories
import net.corda.core.internal.createDirectory import net.corda.core.internal.createDirectory
import net.corda.core.internal.uncheckedCast import net.corda.core.internal.uncheckedCast
@ -163,6 +164,14 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
return defaultNotaryNode.info.legalIdentities[1] // TODO Resolve once network parameters is merged back in return defaultNotaryNode.info.legalIdentities[1] // TODO Resolve once network parameters is merged back in
} }
/**
* Return the identity of the default notary node.
* @see defaultNotaryNode
*/
val defaultNotaryIdentityAndCert: PartyAndCertificate get() {
return defaultNotaryNode.info.legalIdentitiesAndCerts.singleOrNull() ?: throw IllegalStateException("Default notary has multiple identities")
}
/** /**
* Because this executor is shared, we need to be careful about nodes shutting it down. * Because this executor is shared, we need to be careful about nodes shutting it down.
*/ */