mirror of
https://github.com/corda/corda.git
synced 2025-06-17 06:38:21 +00:00
Move tests to using named identities (#1879)
Move tests to using named identities in preparation for multiple identities work. Includes: * NetworkMapCacheTest * NodeInterestRatesTest * NodeVaultServiceTest * ContractUpgradeFlowTest * Cash tests * AttachmentSerializationTest * CordaRPCOpsImplTest * VaultWithCashTest * ScheduledFlowTests
This commit is contained in:
@ -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)}" }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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\"")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
},
|
},
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 ->
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user