mirror of
https://github.com/corda/corda.git
synced 2025-05-29 13:44:25 +00:00
Removed the ability to manually start notary nodes from the driver and MockNetwork. Instead by default a single notary is automatically started. This can be customised at creation time of the driver and MockNetwork. This more accurately models the concept of network parameters in a CZ.
Also added helper methods to retrieve this default notary.
This commit is contained in:
parent
9be37c2b88
commit
3bb018a5ce
@ -11,7 +11,6 @@ import net.corda.core.flows.StateMachineRunId
|
|||||||
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.internal.bufferUntilSubscribed
|
import net.corda.core.internal.bufferUntilSubscribed
|
||||||
import net.corda.core.internal.concurrent.transpose
|
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
import net.corda.core.messaging.StateMachineTransactionMapping
|
import net.corda.core.messaging.StateMachineTransactionMapping
|
||||||
import net.corda.core.messaging.StateMachineUpdate
|
import net.corda.core.messaging.StateMachineUpdate
|
||||||
@ -50,44 +49,44 @@ class NodeMonitorModelTest {
|
|||||||
private lateinit var vaultUpdates: Observable<Vault.Update<ContractState>>
|
private lateinit var vaultUpdates: Observable<Vault.Update<ContractState>>
|
||||||
private lateinit var networkMapUpdates: Observable<NetworkMapCache.MapChange>
|
private lateinit var networkMapUpdates: Observable<NetworkMapCache.MapChange>
|
||||||
private lateinit var newNode: (CordaX500Name) -> NodeInfo
|
private lateinit var newNode: (CordaX500Name) -> NodeInfo
|
||||||
private fun setup(runTest: () -> Unit) = driver(extraCordappPackagesToScan = listOf("net.corda.finance")) {
|
|
||||||
val cashUser = User("user1", "test", permissions = setOf(
|
|
||||||
startFlow<CashIssueFlow>(),
|
|
||||||
startFlow<CashPaymentFlow>(),
|
|
||||||
startFlow<CashExitFlow>(),
|
|
||||||
invokeRpc(CordaRPCOps::notaryIdentities),
|
|
||||||
invokeRpc("vaultTrackBy"),
|
|
||||||
invokeRpc("vaultQueryBy"),
|
|
||||||
invokeRpc(CordaRPCOps::internalVerifiedTransactionsFeed),
|
|
||||||
invokeRpc(CordaRPCOps::stateMachineRecordedTransactionMappingFeed),
|
|
||||||
invokeRpc(CordaRPCOps::stateMachinesFeed),
|
|
||||||
invokeRpc(CordaRPCOps::networkMapFeed))
|
|
||||||
)
|
|
||||||
val (notaryHandle, aliceNodeHandle) = listOf(
|
|
||||||
startNotaryNode(DUMMY_NOTARY.name, validating = false),
|
|
||||||
startNode(providedName = ALICE.name, rpcUsers = listOf(cashUser))
|
|
||||||
).transpose().getOrThrow()
|
|
||||||
aliceNode = aliceNodeHandle.nodeInfo
|
|
||||||
newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo }
|
|
||||||
val monitor = NodeMonitorModel()
|
|
||||||
stateMachineTransactionMapping = monitor.stateMachineTransactionMapping.bufferUntilSubscribed()
|
|
||||||
stateMachineUpdates = monitor.stateMachineUpdates.bufferUntilSubscribed()
|
|
||||||
progressTracking = monitor.progressTracking.bufferUntilSubscribed()
|
|
||||||
transactions = monitor.transactions.bufferUntilSubscribed()
|
|
||||||
vaultUpdates = monitor.vaultUpdates.bufferUntilSubscribed()
|
|
||||||
networkMapUpdates = monitor.networkMap.bufferUntilSubscribed()
|
|
||||||
|
|
||||||
monitor.register(aliceNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password)
|
private fun setup(runTest: () -> Unit) {
|
||||||
rpc = monitor.proxyObservable.value!!
|
driver(extraCordappPackagesToScan = listOf("net.corda.finance")) {
|
||||||
notaryParty = notaryHandle.nodeInfo.legalIdentities[0]
|
val cashUser = User("user1", "test", permissions = setOf(
|
||||||
|
startFlow<CashIssueFlow>(),
|
||||||
|
startFlow<CashPaymentFlow>(),
|
||||||
|
startFlow<CashExitFlow>(),
|
||||||
|
invokeRpc(CordaRPCOps::notaryIdentities),
|
||||||
|
invokeRpc("vaultTrackBy"),
|
||||||
|
invokeRpc("vaultQueryBy"),
|
||||||
|
invokeRpc(CordaRPCOps::internalVerifiedTransactionsFeed),
|
||||||
|
invokeRpc(CordaRPCOps::stateMachineRecordedTransactionMappingFeed),
|
||||||
|
invokeRpc(CordaRPCOps::stateMachinesFeed),
|
||||||
|
invokeRpc(CordaRPCOps::networkMapFeed))
|
||||||
|
)
|
||||||
|
val aliceNodeHandle = startNode(providedName = ALICE.name, rpcUsers = listOf(cashUser)).getOrThrow()
|
||||||
|
aliceNode = aliceNodeHandle.nodeInfo
|
||||||
|
newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo }
|
||||||
|
val monitor = NodeMonitorModel()
|
||||||
|
stateMachineTransactionMapping = monitor.stateMachineTransactionMapping.bufferUntilSubscribed()
|
||||||
|
stateMachineUpdates = monitor.stateMachineUpdates.bufferUntilSubscribed()
|
||||||
|
progressTracking = monitor.progressTracking.bufferUntilSubscribed()
|
||||||
|
transactions = monitor.transactions.bufferUntilSubscribed()
|
||||||
|
vaultUpdates = monitor.vaultUpdates.bufferUntilSubscribed()
|
||||||
|
networkMapUpdates = monitor.networkMap.bufferUntilSubscribed()
|
||||||
|
|
||||||
val bobNodeHandle = startNode(providedName = BOB.name, rpcUsers = listOf(cashUser)).getOrThrow()
|
monitor.register(aliceNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password)
|
||||||
bobNode = bobNodeHandle.nodeInfo
|
rpc = monitor.proxyObservable.value!!
|
||||||
val monitorBob = NodeMonitorModel()
|
notaryParty = defaultNotaryIdentity
|
||||||
stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed()
|
|
||||||
monitorBob.register(bobNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password)
|
val bobNodeHandle = startNode(providedName = BOB.name, rpcUsers = listOf(cashUser)).getOrThrow()
|
||||||
rpcBob = monitorBob.proxyObservable.value!!
|
bobNode = bobNodeHandle.nodeInfo
|
||||||
runTest()
|
val monitorBob = NodeMonitorModel()
|
||||||
|
stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed()
|
||||||
|
monitorBob.register(bobNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password)
|
||||||
|
rpcBob = monitorBob.proxyObservable.value!!
|
||||||
|
runTest()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -14,8 +14,11 @@ import net.corda.finance.DOLLARS
|
|||||||
import net.corda.finance.contracts.asset.Cash
|
import net.corda.finance.contracts.asset.Cash
|
||||||
import net.corda.finance.flows.CashIssueAndPaymentFlow
|
import net.corda.finance.flows.CashIssueAndPaymentFlow
|
||||||
import net.corda.finance.flows.CashPaymentFlow
|
import net.corda.finance.flows.CashPaymentFlow
|
||||||
import net.corda.testing.*
|
import net.corda.testing.ALICE_NAME
|
||||||
|
import net.corda.testing.BOB_NAME
|
||||||
|
import net.corda.testing.CHARLIE_NAME
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
|
import net.corda.testing.singleIdentity
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -24,12 +27,16 @@ import kotlin.test.assertNotNull
|
|||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
|
|
||||||
class IdentitySyncFlowTests {
|
class IdentitySyncFlowTests {
|
||||||
lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun before() {
|
fun before() {
|
||||||
// We run this in parallel threads to help catch any race conditions that may exist.
|
// We run this in parallel threads to help catch any race conditions that may exist.
|
||||||
mockNet = MockNetwork(networkSendManuallyPumped = false, threadPerNode = true, cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
mockNet = MockNetwork(
|
||||||
|
networkSendManuallyPumped = false,
|
||||||
|
threadPerNode = true,
|
||||||
|
cordappPackages = listOf("net.corda.finance.contracts.asset")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@ -40,12 +47,11 @@ class IdentitySyncFlowTests {
|
|||||||
@Test
|
@Test
|
||||||
fun `sync confidential identities`() {
|
fun `sync confidential identities`() {
|
||||||
// Set up values we'll need
|
// Set up values we'll need
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
|
||||||
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 alice: Party = aliceNode.info.singleIdentity()
|
val alice: Party = aliceNode.info.singleIdentity()
|
||||||
val bob: Party = bobNode.info.singleIdentity()
|
val bob: Party = bobNode.info.singleIdentity()
|
||||||
val notary = notaryNode.services.getDefaultNotary()
|
val notary = mockNet.defaultNotaryIdentity
|
||||||
bobNode.internals.registerInitiatedFlow(Receive::class.java)
|
bobNode.internals.registerInitiatedFlow(Receive::class.java)
|
||||||
|
|
||||||
// Alice issues then pays some cash to a new confidential identity that Bob doesn't know about
|
// Alice issues then pays some cash to a new confidential identity that Bob doesn't know about
|
||||||
@ -70,14 +76,13 @@ class IdentitySyncFlowTests {
|
|||||||
@Test
|
@Test
|
||||||
fun `don't offer other's identities confidential identities`() {
|
fun `don't offer other's identities confidential identities`() {
|
||||||
// Set up values we'll need
|
// Set up values we'll need
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
|
||||||
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 charlieNode = mockNet.createPartyNode(CHARLIE_NAME)
|
val charlieNode = mockNet.createPartyNode(CHARLIE_NAME)
|
||||||
val alice: Party = aliceNode.info.singleIdentity()
|
val alice: Party = aliceNode.info.singleIdentity()
|
||||||
val bob: Party = bobNode.info.singleIdentity()
|
val bob: Party = bobNode.info.singleIdentity()
|
||||||
val charlie: Party = charlieNode.info.singleIdentity()
|
val charlie: Party = charlieNode.info.singleIdentity()
|
||||||
val notary = notaryNode.services.getDefaultNotary()
|
val notary = mockNet.defaultNotaryIdentity
|
||||||
bobNode.internals.registerInitiatedFlow(Receive::class.java)
|
bobNode.internals.registerInitiatedFlow(Receive::class.java)
|
||||||
|
|
||||||
// Charlie issues then pays some cash to a new confidential identity
|
// Charlie issues then pays some cash to a new confidential identity
|
||||||
@ -105,7 +110,7 @@ class IdentitySyncFlowTests {
|
|||||||
* Very lightweight wrapping flow to trigger the counterparty flow that receives the identities.
|
* Very lightweight wrapping flow to trigger the counterparty flow that receives the identities.
|
||||||
*/
|
*/
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
class Initiator(val otherSide: Party, val tx: WireTransaction): FlowLogic<Boolean>() {
|
class Initiator(private val otherSide: Party, private val tx: WireTransaction): FlowLogic<Boolean>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): Boolean {
|
override fun call(): Boolean {
|
||||||
val session = initiateFlow(otherSide)
|
val session = initiateFlow(otherSide)
|
||||||
@ -116,7 +121,7 @@ class IdentitySyncFlowTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@InitiatedBy(IdentitySyncFlowTests.Initiator::class)
|
@InitiatedBy(IdentitySyncFlowTests.Initiator::class)
|
||||||
class Receive(val otherSideSession: FlowSession): FlowLogic<Unit>() {
|
class Receive(private val otherSideSession: FlowSession): FlowLogic<Unit>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() {
|
override fun call() {
|
||||||
subFlow(IdentitySyncFlow.Receive(otherSideSession))
|
subFlow(IdentitySyncFlow.Receive(otherSideSession))
|
||||||
|
@ -6,17 +6,22 @@ import net.corda.core.identity.Party
|
|||||||
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.Test
|
import org.junit.Test
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
class SwapIdentitiesFlowTests {
|
class SwapIdentitiesFlowTests {
|
||||||
|
private lateinit var mockNet: MockNetwork
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
// We run this in parallel threads to help catch any race conditions that may exist.
|
||||||
|
mockNet = MockNetwork(networkSendManuallyPumped = false, threadPerNode = true)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `issue key`() {
|
fun `issue key`() {
|
||||||
// We run this in parallel threads to help catch any race conditions that may exist.
|
|
||||||
val mockNet = MockNetwork(threadPerNode = true)
|
|
||||||
|
|
||||||
// Set up values we'll need
|
// Set up values we'll need
|
||||||
mockNet.createNotaryNode()
|
|
||||||
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 alice = aliceNode.info.singleIdentity()
|
val alice = aliceNode.info.singleIdentity()
|
||||||
@ -52,19 +57,16 @@ class SwapIdentitiesFlowTests {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun `verifies identity name`() {
|
fun `verifies identity name`() {
|
||||||
// We run this in parallel threads to help catch any race conditions that may exist.
|
|
||||||
val mockNet = MockNetwork(threadPerNode = true)
|
|
||||||
|
|
||||||
// Set up values we'll need
|
// Set up values we'll need
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
|
||||||
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 charlieNode = mockNet.createPartyNode(CHARLIE.name)
|
||||||
val bob: Party = bobNode.services.myInfo.singleIdentity()
|
val bob: Party = bobNode.services.myInfo.singleIdentity()
|
||||||
val notBob = notaryNode.database.transaction {
|
val notBob = charlieNode.database.transaction {
|
||||||
notaryNode.services.keyManagementService.freshKeyAndCert(notaryNode.services.myInfo.chooseIdentityAndCert(), false)
|
charlieNode.services.keyManagementService.freshKeyAndCert(charlieNode.services.myInfo.chooseIdentityAndCert(), false)
|
||||||
}
|
}
|
||||||
val sigData = SwapIdentitiesFlow.buildDataToSign(notBob)
|
val sigData = SwapIdentitiesFlow.buildDataToSign(notBob)
|
||||||
val signature = notaryNode.services.keyManagementService.sign(sigData, notBob.owningKey)
|
val signature = charlieNode.services.keyManagementService.sign(sigData, notBob.owningKey)
|
||||||
assertFailsWith<SwapIdentitiesException>("Certificate subject must match counterparty's well known identity.") {
|
assertFailsWith<SwapIdentitiesException>("Certificate subject must match counterparty's well known identity.") {
|
||||||
SwapIdentitiesFlow.validateAndRegisterIdentity(aliceNode.services.identityService, bob, notBob, signature.withoutKey())
|
SwapIdentitiesFlow.validateAndRegisterIdentity(aliceNode.services.identityService, bob, notBob, signature.withoutKey())
|
||||||
}
|
}
|
||||||
@ -77,11 +79,8 @@ class SwapIdentitiesFlowTests {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun `verifies signature`() {
|
fun `verifies signature`() {
|
||||||
// We run this in parallel threads to help catch any race conditions that may exist.
|
|
||||||
val mockNet = MockNetwork(threadPerNode = true)
|
|
||||||
|
|
||||||
// Set up values we'll need
|
// Set up values we'll need
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
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 bob: Party = bobNode.services.myInfo.singleIdentity()
|
||||||
|
@ -120,7 +120,7 @@ interface NetworkMapCacheBase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if and only if the given [Party] is validating notary. For every party that is a validating notary,
|
* Returns true if and only if the given [Party] is validating notary. For every party that is a validating notary,
|
||||||
* [isNotary] is only true.
|
* [isNotary] is also true.
|
||||||
* @see isNotary
|
* @see isNotary
|
||||||
*/
|
*/
|
||||||
fun isValidatingNotary(party: Party): Boolean
|
fun isValidatingNotary(party: Party): Boolean
|
||||||
|
@ -18,14 +18,12 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
|||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
public class FlowsInJavaTest {
|
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;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
mockNet.createNotaryNode();
|
|
||||||
aliceNode = mockNet.createPartyNode(TestConstants.getALICE().getName());
|
aliceNode = mockNet.createPartyNode(TestConstants.getALICE().getName());
|
||||||
bobNode = mockNet.createPartyNode(TestConstants.getBOB().getName());
|
bobNode = mockNet.createPartyNode(TestConstants.getBOB().getName());
|
||||||
mockNet.runNetwork();
|
mockNet.runNetwork();
|
||||||
|
@ -110,11 +110,11 @@ class AttachmentTests {
|
|||||||
@Test
|
@Test
|
||||||
fun maliciousResponse() {
|
fun maliciousResponse() {
|
||||||
// Make a node that doesn't do sanity checking at load time.
|
// Make a node that doesn't do sanity checking at load time.
|
||||||
val aliceNode = mockNet.createNotaryNode(MockNodeParameters(legalName = ALICE.name), nodeFactory = { args ->
|
val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE.name), nodeFactory = { args ->
|
||||||
object : MockNetwork.MockNode(args) {
|
object : MockNetwork.MockNode(args) {
|
||||||
override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = false }
|
override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = false }
|
||||||
}
|
}
|
||||||
}, validating = false)
|
})
|
||||||
val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB.name))
|
val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB.name))
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
val alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
|
val alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
|
||||||
|
@ -27,19 +27,18 @@ class CollectSignaturesFlowTests {
|
|||||||
private val cordappPackages = listOf("net.corda.testing.contracts")
|
private val cordappPackages = listOf("net.corda.testing.contracts")
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
|
private lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var bobNode: StartedNode<MockNetwork.MockNode>
|
private lateinit var bobNode: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var charlieNode: StartedNode<MockNetwork.MockNode>
|
private lateinit var charlieNode: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var alice: Party
|
private lateinit var alice: Party
|
||||||
lateinit var bob: Party
|
private lateinit var bob: Party
|
||||||
lateinit var charlie: Party
|
private lateinit var charlie: Party
|
||||||
lateinit var notary: Party
|
private lateinit var notary: Party
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = MockNetwork(cordappPackages = cordappPackages)
|
mockNet = MockNetwork(cordappPackages = cordappPackages)
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
|
||||||
aliceNode = mockNet.createPartyNode(ALICE.name)
|
aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||||
bobNode = mockNet.createPartyNode(BOB.name)
|
bobNode = mockNet.createPartyNode(BOB.name)
|
||||||
charlieNode = mockNet.createPartyNode(CHARLIE.name)
|
charlieNode = mockNet.createPartyNode(CHARLIE.name)
|
||||||
@ -47,7 +46,7 @@ class CollectSignaturesFlowTests {
|
|||||||
alice = aliceNode.info.singleIdentity()
|
alice = aliceNode.info.singleIdentity()
|
||||||
bob = bobNode.info.singleIdentity()
|
bob = bobNode.info.singleIdentity()
|
||||||
charlie = charlieNode.info.singleIdentity()
|
charlie = charlieNode.info.singleIdentity()
|
||||||
notary = notaryNode.services.getDefaultNotary()
|
notary = mockNet.defaultNotaryIdentity
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -41,14 +41,13 @@ class ContractUpgradeFlowTest {
|
|||||||
@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"))
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
|
||||||
aliceNode = mockNet.createPartyNode(ALICE.name)
|
aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||||
bobNode = mockNet.createPartyNode(BOB.name)
|
bobNode = mockNet.createPartyNode(BOB.name)
|
||||||
|
|
||||||
// Process registration
|
// Process registration
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
|
|
||||||
notary = notaryNode.services.getDefaultNotary()
|
notary = mockNet.defaultNotaryIdentity
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -26,7 +26,6 @@ class FinalityFlowTests {
|
|||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
|
||||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||||
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
@ -34,7 +33,7 @@ class FinalityFlowTests {
|
|||||||
bobServices = bobNode.services
|
bobServices = bobNode.services
|
||||||
alice = aliceNode.info.singleIdentity()
|
alice = aliceNode.info.singleIdentity()
|
||||||
bob = bobNode.info.singleIdentity()
|
bob = bobNode.info.singleIdentity()
|
||||||
notary = notaryNode.services.getDefaultNotary()
|
notary = aliceServices.getDefaultNotary()
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -13,7 +13,7 @@ import org.junit.Test
|
|||||||
class ReceiveMultipleFlowTests {
|
class ReceiveMultipleFlowTests {
|
||||||
@Test
|
@Test
|
||||||
fun `receive all messages in parallel using map style`() {
|
fun `receive all messages in parallel using map style`() {
|
||||||
network(3) { nodes, _ ->
|
network(3) { nodes ->
|
||||||
val doubleValue = 5.0
|
val doubleValue = 5.0
|
||||||
nodes[1].registerAnswer(AlgorithmDefinition::class, doubleValue)
|
nodes[1].registerAnswer(AlgorithmDefinition::class, doubleValue)
|
||||||
val stringValue = "Thriller"
|
val stringValue = "Thriller"
|
||||||
@ -30,7 +30,7 @@ class ReceiveMultipleFlowTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `receive all messages in parallel using list style`() {
|
fun `receive all messages in parallel using list style`() {
|
||||||
network(3) { nodes, _ ->
|
network(3) { nodes ->
|
||||||
val value1 = 5.0
|
val value1 = 5.0
|
||||||
nodes[1].registerAnswer(ParallelAlgorithmList::class, value1)
|
nodes[1].registerAnswer(ParallelAlgorithmList::class, value1)
|
||||||
val value2 = 6.0
|
val value2 = 6.0
|
||||||
|
@ -8,7 +8,9 @@ import net.corda.core.transactions.SignedTransaction
|
|||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.core.utilities.sequence
|
import net.corda.core.utilities.sequence
|
||||||
import net.corda.node.internal.StartedNode
|
import net.corda.node.internal.StartedNode
|
||||||
import net.corda.testing.*
|
import net.corda.testing.MEGA_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.getDefaultNotary
|
import net.corda.testing.getDefaultNotary
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
@ -26,18 +28,18 @@ import kotlin.test.assertNull
|
|||||||
|
|
||||||
// DOCSTART 3
|
// DOCSTART 3
|
||||||
class ResolveTransactionsFlowTest {
|
class ResolveTransactionsFlowTest {
|
||||||
lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
|
private lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var megaCorpNode: StartedNode<MockNetwork.MockNode>
|
private lateinit var megaCorpNode: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var miniCorpNode: StartedNode<MockNetwork.MockNode>
|
private lateinit var miniCorpNode: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var megaCorp: Party
|
private lateinit var megaCorp: Party
|
||||||
lateinit var miniCorp: Party
|
private lateinit var miniCorp: Party
|
||||||
lateinit var notary: Party
|
private lateinit var notary: Party
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts"))
|
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts"))
|
||||||
notaryNode = mockNet.createNotaryNode()
|
notaryNode = mockNet.defaultNotaryNode
|
||||||
megaCorpNode = mockNet.createPartyNode(MEGA_CORP.name)
|
megaCorpNode = mockNet.createPartyNode(MEGA_CORP.name)
|
||||||
miniCorpNode = mockNet.createPartyNode(MINI_CORP.name)
|
miniCorpNode = mockNet.createPartyNode(MINI_CORP.name)
|
||||||
megaCorpNode.internals.registerInitiatedFlow(TestResponseFlow::class.java)
|
megaCorpNode.internals.registerInitiatedFlow(TestResponseFlow::class.java)
|
||||||
|
@ -37,8 +37,7 @@ class IntegrationTestingTutorial {
|
|||||||
invokeRpc("vaultTrackBy"),
|
invokeRpc("vaultTrackBy"),
|
||||||
invokeRpc(CordaRPCOps::networkMapFeed)
|
invokeRpc(CordaRPCOps::networkMapFeed)
|
||||||
))
|
))
|
||||||
val (_, alice, bob) = listOf(
|
val (alice, bob) = listOf(
|
||||||
startNotaryNode(DUMMY_NOTARY.name),
|
|
||||||
startNode(providedName = ALICE.name, rpcUsers = listOf(aliceUser)),
|
startNode(providedName = ALICE.name, rpcUsers = listOf(aliceUser)),
|
||||||
startNode(providedName = BOB.name, rpcUsers = listOf(bobUser))
|
startNode(providedName = BOB.name, rpcUsers = listOf(bobUser))
|
||||||
).transpose().getOrThrow()
|
).transpose().getOrThrow()
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
package net.corda.docs
|
package net.corda.docs
|
||||||
|
|
||||||
import net.corda.core.contracts.Amount
|
import net.corda.core.contracts.Amount
|
||||||
@ -17,7 +19,6 @@ import net.corda.node.services.Permissions.Companion.invokeRpc
|
|||||||
import net.corda.node.services.Permissions.Companion.startFlow
|
import net.corda.node.services.Permissions.Companion.startFlow
|
||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.ALICE
|
import net.corda.testing.ALICE
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import org.graphstream.graph.Edge
|
import org.graphstream.graph.Edge
|
||||||
import org.graphstream.graph.Node
|
import org.graphstream.graph.Node
|
||||||
@ -48,7 +49,6 @@ fun main(args: Array<String>) {
|
|||||||
invokeRpc(CordaRPCOps::nodeInfo)
|
invokeRpc(CordaRPCOps::nodeInfo)
|
||||||
))
|
))
|
||||||
driver(driverDirectory = baseDirectory, extraCordappPackagesToScan = listOf("net.corda.finance")) {
|
driver(driverDirectory = baseDirectory, extraCordappPackagesToScan = listOf("net.corda.finance")) {
|
||||||
startNotaryNode(DUMMY_NOTARY.name)
|
|
||||||
val node = startNode(providedName = ALICE.name, rpcUsers = listOf(user)).get()
|
val node = startNode(providedName = ALICE.name, rpcUsers = listOf(user)).get()
|
||||||
// END 1
|
// END 1
|
||||||
|
|
||||||
|
@ -55,7 +55,6 @@ class TutorialMockNetwork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lateinit private var mockNet: MockNetwork
|
lateinit private var mockNet: MockNetwork
|
||||||
lateinit private var notary: StartedNode<MockNetwork.MockNode>
|
|
||||||
lateinit private var nodeA: StartedNode<MockNetwork.MockNode>
|
lateinit private var nodeA: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit private var nodeB: StartedNode<MockNetwork.MockNode>
|
lateinit private var nodeB: StartedNode<MockNetwork.MockNode>
|
||||||
|
|
||||||
@ -66,7 +65,6 @@ class TutorialMockNetwork {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
mockNet = MockNetwork()
|
mockNet = MockNetwork()
|
||||||
notary = mockNet.createNotaryNode()
|
|
||||||
nodeA = mockNet.createPartyNode()
|
nodeA = mockNet.createPartyNode()
|
||||||
nodeB = mockNet.createPartyNode()
|
nodeB = mockNet.createPartyNode()
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@ import net.corda.finance.contracts.getCashBalances
|
|||||||
import net.corda.finance.flows.CashIssueFlow
|
import net.corda.finance.flows.CashIssueFlow
|
||||||
import net.corda.finance.schemas.CashSchemaV1
|
import net.corda.finance.schemas.CashSchemaV1
|
||||||
import net.corda.node.internal.StartedNode
|
import net.corda.node.internal.StartedNode
|
||||||
import net.corda.testing.*
|
import net.corda.testing.chooseIdentity
|
||||||
|
import net.corda.testing.getDefaultNotary
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
@ -19,23 +20,20 @@ import org.junit.Test
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class CustomVaultQueryTest {
|
class CustomVaultQueryTest {
|
||||||
|
private lateinit var mockNet: MockNetwork
|
||||||
lateinit var mockNet: MockNetwork
|
private lateinit var nodeA: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var nodeA: StartedNode<MockNetwork.MockNode>
|
private lateinit var nodeB: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var nodeB: StartedNode<MockNetwork.MockNode>
|
private lateinit var notary: Party
|
||||||
lateinit var notary: Party
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = MockNetwork(
|
mockNet = MockNetwork(threadPerNode = true,
|
||||||
threadPerNode = true,
|
|
||||||
cordappPackages = listOf(
|
cordappPackages = listOf(
|
||||||
"net.corda.finance.contracts.asset",
|
"net.corda.finance.contracts.asset",
|
||||||
CashSchemaV1::class.packageName,
|
CashSchemaV1::class.packageName,
|
||||||
"net.corda.docs"
|
"net.corda.docs"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
mockNet.createNotaryNode()
|
|
||||||
nodeA = mockNet.createPartyNode()
|
nodeA = mockNet.createPartyNode()
|
||||||
nodeB = mockNet.createPartyNode()
|
nodeB = mockNet.createPartyNode()
|
||||||
nodeA.internals.registerInitiatedFlow(TopupIssuerFlow.TopupIssuer::class.java)
|
nodeA.internals.registerInitiatedFlow(TopupIssuerFlow.TopupIssuer::class.java)
|
||||||
|
@ -10,7 +10,8 @@ import net.corda.finance.contracts.getCashBalances
|
|||||||
import net.corda.finance.flows.CashIssueFlow
|
import net.corda.finance.flows.CashIssueFlow
|
||||||
import net.corda.finance.schemas.CashSchemaV1
|
import net.corda.finance.schemas.CashSchemaV1
|
||||||
import net.corda.node.internal.StartedNode
|
import net.corda.node.internal.StartedNode
|
||||||
import net.corda.testing.*
|
import net.corda.testing.chooseIdentity
|
||||||
|
import net.corda.testing.getDefaultNotary
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -18,15 +19,14 @@ import org.junit.Test
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class FxTransactionBuildTutorialTest {
|
class FxTransactionBuildTutorialTest {
|
||||||
lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
lateinit var nodeA: StartedNode<MockNetwork.MockNode>
|
private lateinit var nodeA: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var nodeB: StartedNode<MockNetwork.MockNode>
|
private lateinit var nodeB: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var notary: Party
|
private lateinit var notary: Party
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance.contracts.asset", CashSchemaV1::class.packageName))
|
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance.contracts.asset", CashSchemaV1::class.packageName))
|
||||||
mockNet.createNotaryNode()
|
|
||||||
nodeA = mockNet.createPartyNode()
|
nodeA = mockNet.createPartyNode()
|
||||||
nodeB = mockNet.createPartyNode()
|
nodeB = mockNet.createPartyNode()
|
||||||
nodeB.internals.registerInitiatedFlow(ForeignExchangeRemoteFlow::class.java)
|
nodeB.internals.registerInitiatedFlow(ForeignExchangeRemoteFlow::class.java)
|
||||||
|
@ -10,7 +10,8 @@ import net.corda.core.node.services.vault.QueryCriteria
|
|||||||
import net.corda.core.toFuture
|
import net.corda.core.toFuture
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.node.services.api.StartedNodeServices
|
import net.corda.node.services.api.StartedNodeServices
|
||||||
import net.corda.testing.*
|
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 org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -18,11 +19,11 @@ import org.junit.Test
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class WorkflowTransactionBuildTutorialTest {
|
class WorkflowTransactionBuildTutorialTest {
|
||||||
lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
lateinit var aliceServices: StartedNodeServices
|
private lateinit var aliceServices: StartedNodeServices
|
||||||
lateinit var bobServices: StartedNodeServices
|
private lateinit var bobServices: StartedNodeServices
|
||||||
lateinit var alice: Party
|
private lateinit var alice: Party
|
||||||
lateinit var bob: Party
|
private lateinit var bob: Party
|
||||||
|
|
||||||
// Helper method to locate the latest Vault version of a LinearState
|
// Helper method to locate the latest Vault version of a LinearState
|
||||||
private inline fun <reified T : LinearState> ServiceHub.latest(ref: UniqueIdentifier): StateAndRef<T> {
|
private inline fun <reified T : LinearState> ServiceHub.latest(ref: UniqueIdentifier): StateAndRef<T> {
|
||||||
@ -33,8 +34,6 @@ class WorkflowTransactionBuildTutorialTest {
|
|||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.docs"))
|
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.docs"))
|
||||||
// While we don't use the notary, we need there to be one on the network
|
|
||||||
mockNet.createNotaryNode()
|
|
||||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||||
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||||
aliceNode.internals.registerInitiatedFlow(RecordCompletionFlow::class.java)
|
aliceNode.internals.registerInitiatedFlow(RecordCompletionFlow::class.java)
|
||||||
|
@ -1,41 +1,38 @@
|
|||||||
package net.corda.finance.contracts.asset
|
package net.corda.finance.contracts.asset
|
||||||
|
|
||||||
import net.corda.core.internal.packageName
|
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.finance.DOLLARS
|
import net.corda.finance.DOLLARS
|
||||||
import net.corda.finance.flows.CashException
|
import net.corda.finance.flows.CashException
|
||||||
import net.corda.finance.flows.CashPaymentFlow
|
import net.corda.finance.flows.CashPaymentFlow
|
||||||
import net.corda.finance.schemas.CashSchemaV1
|
|
||||||
import net.corda.testing.chooseIdentity
|
|
||||||
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 org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
|
import org.junit.After
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
||||||
class CashSelectionH2Test {
|
class CashSelectionH2Test {
|
||||||
|
private val mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance"))
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun cleanUp() {
|
||||||
|
mockNet.stopNodes()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `check does not hold connection over retries`() {
|
fun `check does not hold connection over retries`() {
|
||||||
val mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance.contracts.asset", CashSchemaV1::class.packageName))
|
val bankA = mockNet.createNode(MockNodeParameters(configOverrides = {
|
||||||
try {
|
// Tweak connections to be minimal to make this easier (1 results in a hung node during start up, so use 2 connections).
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
it.dataSourceProperties.setProperty("maximumPoolSize", "2")
|
||||||
val bankA = mockNet.createNode(MockNodeParameters(configOverrides = { existingConfig ->
|
}))
|
||||||
// Tweak connections to be minimal to make this easier (1 results in a hung node during start up, so use 2 connections).
|
val notary = mockNet.defaultNotaryIdentity
|
||||||
existingConfig.dataSourceProperties.setProperty("maximumPoolSize", "2")
|
|
||||||
}))
|
|
||||||
mockNet.startNodes()
|
|
||||||
|
|
||||||
// Start more cash spends than we have connections. If spend leaks a connection on retry, we will run out of connections.
|
// Start more cash spends than we have connections. If spend leaks a connection on retry, we will run out of connections.
|
||||||
val flow1 = bankA.services.startFlow(CashPaymentFlow(amount = 100.DOLLARS, anonymous = false, recipient = notaryNode.info.chooseIdentity()))
|
val flow1 = bankA.services.startFlow(CashPaymentFlow(amount = 100.DOLLARS, anonymous = false, recipient = notary))
|
||||||
val flow2 = bankA.services.startFlow(CashPaymentFlow(amount = 100.DOLLARS, anonymous = false, recipient = notaryNode.info.chooseIdentity()))
|
val flow2 = bankA.services.startFlow(CashPaymentFlow(amount = 100.DOLLARS, anonymous = false, recipient = notary))
|
||||||
val flow3 = bankA.services.startFlow(CashPaymentFlow(amount = 100.DOLLARS, anonymous = false, recipient = notaryNode.info.chooseIdentity()))
|
val flow3 = bankA.services.startFlow(CashPaymentFlow(amount = 100.DOLLARS, anonymous = false, recipient = notary))
|
||||||
|
|
||||||
assertThatThrownBy { flow1.resultFuture.getOrThrow() }.isInstanceOf(CashException::class.java)
|
assertThatThrownBy { flow1.resultFuture.getOrThrow() }.isInstanceOf(CashException::class.java)
|
||||||
assertThatThrownBy { flow2.resultFuture.getOrThrow() }.isInstanceOf(CashException::class.java)
|
assertThatThrownBy { flow2.resultFuture.getOrThrow() }.isInstanceOf(CashException::class.java)
|
||||||
assertThatThrownBy { flow3.resultFuture.getOrThrow() }.isInstanceOf(CashException::class.java)
|
assertThatThrownBy { flow3.resultFuture.getOrThrow() }.isInstanceOf(CashException::class.java)
|
||||||
} finally {
|
|
||||||
mockNet.stopNodes()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,7 +7,9 @@ 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.*
|
import net.corda.testing.BOC
|
||||||
|
import net.corda.testing.chooseIdentity
|
||||||
|
import net.corda.testing.getDefaultNotary
|
||||||
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
|
||||||
@ -23,15 +25,13 @@ class CashExitFlowTests {
|
|||||||
private val ref = OpaqueBytes.of(0x01)
|
private val ref = OpaqueBytes.of(0x01)
|
||||||
private lateinit var bankOfCordaNode: StartedNode<MockNode>
|
private lateinit var bankOfCordaNode: StartedNode<MockNode>
|
||||||
private lateinit var bankOfCorda: Party
|
private lateinit var bankOfCorda: Party
|
||||||
private lateinit var notaryNode: StartedNode<MockNode>
|
|
||||||
private lateinit var notary: Party
|
private lateinit var notary: Party
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun start() {
|
fun start() {
|
||||||
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(),
|
||||||
notaryNode = mockNet.createNotaryNode()
|
cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
||||||
bankOfCordaNode = mockNet.createPartyNode(BOC.name)
|
bankOfCordaNode = mockNet.createPartyNode(BOC.name)
|
||||||
notary = notaryNode.services.getDefaultNotary()
|
|
||||||
bankOfCorda = bankOfCordaNode.info.chooseIdentity()
|
bankOfCorda = bankOfCordaNode.info.chooseIdentity()
|
||||||
|
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
|
@ -7,9 +7,8 @@ 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.chooseIdentity
|
|
||||||
import net.corda.testing.getDefaultNotary
|
|
||||||
import net.corda.testing.BOC
|
import net.corda.testing.BOC
|
||||||
|
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
|
||||||
@ -23,16 +22,14 @@ class CashIssueFlowTests {
|
|||||||
private lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
private lateinit var bankOfCordaNode: StartedNode<MockNode>
|
private lateinit var bankOfCordaNode: StartedNode<MockNode>
|
||||||
private lateinit var bankOfCorda: Party
|
private lateinit var bankOfCorda: Party
|
||||||
private lateinit var notaryNode: StartedNode<MockNode>
|
|
||||||
private lateinit var notary: Party
|
private lateinit var notary: Party
|
||||||
|
|
||||||
@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"))
|
||||||
notaryNode = mockNet.createNotaryNode()
|
|
||||||
bankOfCordaNode = mockNet.createPartyNode(BOC.name)
|
bankOfCordaNode = mockNet.createPartyNode(BOC.name)
|
||||||
bankOfCorda = bankOfCordaNode.info.chooseIdentity()
|
bankOfCorda = bankOfCordaNode.info.chooseIdentity()
|
||||||
notary = notaryNode.services.getDefaultNotary()
|
notary = mockNet.defaultNotaryIdentity
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,18 +26,16 @@ class CashPaymentFlowTests {
|
|||||||
private val ref = OpaqueBytes.of(0x01)
|
private val ref = OpaqueBytes.of(0x01)
|
||||||
private lateinit var bankOfCordaNode: StartedNode<MockNode>
|
private lateinit var bankOfCordaNode: StartedNode<MockNode>
|
||||||
private lateinit var bankOfCorda: Party
|
private lateinit var bankOfCorda: Party
|
||||||
private lateinit var notaryNode: StartedNode<MockNode>
|
private lateinit var aliceNode: StartedNode<MockNode>
|
||||||
private lateinit var notary: Party
|
|
||||||
|
|
||||||
@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"))
|
||||||
notaryNode = mockNet.createNotaryNode()
|
|
||||||
bankOfCordaNode = mockNet.createPartyNode(BOC.name)
|
bankOfCordaNode = mockNet.createPartyNode(BOC.name)
|
||||||
|
aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||||
bankOfCorda = bankOfCordaNode.info.chooseIdentity()
|
bankOfCorda = bankOfCordaNode.info.chooseIdentity()
|
||||||
notary = notaryNode.services.getDefaultNotary()
|
|
||||||
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture
|
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
|
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, mockNet.defaultNotaryIdentity)).resultFuture
|
||||||
future.getOrThrow()
|
future.getOrThrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +46,7 @@ class CashPaymentFlowTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `pay some cash`() {
|
fun `pay some cash`() {
|
||||||
val payTo = notaryNode.info.chooseIdentity()
|
val payTo = aliceNode.info.chooseIdentity()
|
||||||
val expectedPayment = 500.DOLLARS
|
val expectedPayment = 500.DOLLARS
|
||||||
val expectedChange = 1500.DOLLARS
|
val expectedChange = 1500.DOLLARS
|
||||||
|
|
||||||
@ -56,7 +54,7 @@ class CashPaymentFlowTests {
|
|||||||
// Register for vault updates
|
// Register for vault updates
|
||||||
val criteria = QueryCriteria.VaultQueryCriteria(status = Vault.StateStatus.ALL)
|
val criteria = QueryCriteria.VaultQueryCriteria(status = Vault.StateStatus.ALL)
|
||||||
val (_, vaultUpdatesBoc) = bankOfCordaNode.services.vaultService.trackBy<Cash.State>(criteria)
|
val (_, vaultUpdatesBoc) = bankOfCordaNode.services.vaultService.trackBy<Cash.State>(criteria)
|
||||||
val (_, vaultUpdatesBankClient) = notaryNode.services.vaultService.trackBy<Cash.State>(criteria)
|
val (_, vaultUpdatesBankClient) = aliceNode.services.vaultService.trackBy<Cash.State>(criteria)
|
||||||
|
|
||||||
val future = bankOfCordaNode.services.startFlow(CashPaymentFlow(expectedPayment,
|
val future = bankOfCordaNode.services.startFlow(CashPaymentFlow(expectedPayment,
|
||||||
payTo)).resultFuture
|
payTo)).resultFuture
|
||||||
@ -88,7 +86,7 @@ class CashPaymentFlowTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `pay more than we have`() {
|
fun `pay more than we have`() {
|
||||||
val payTo = notaryNode.info.chooseIdentity()
|
val payTo = aliceNode.info.chooseIdentity()
|
||||||
val expected = 4000.DOLLARS
|
val expected = 4000.DOLLARS
|
||||||
val future = bankOfCordaNode.services.startFlow(CashPaymentFlow(expected,
|
val future = bankOfCordaNode.services.startFlow(CashPaymentFlow(expected,
|
||||||
payTo)).resultFuture
|
payTo)).resultFuture
|
||||||
@ -100,7 +98,7 @@ class CashPaymentFlowTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `pay zero cash`() {
|
fun `pay zero cash`() {
|
||||||
val payTo = notaryNode.info.chooseIdentity()
|
val payTo = aliceNode.info.chooseIdentity()
|
||||||
val expected = 0.DOLLARS
|
val expected = 0.DOLLARS
|
||||||
val future = bankOfCordaNode.services.startFlow(CashPaymentFlow(expected,
|
val future = bankOfCordaNode.services.startFlow(CashPaymentFlow(expected,
|
||||||
payTo)).resultFuture
|
payTo)).resultFuture
|
||||||
|
@ -15,9 +15,9 @@ import net.corda.finance.flows.CashPaymentFlow
|
|||||||
import net.corda.node.services.Permissions.Companion.startFlow
|
import net.corda.node.services.Permissions.Companion.startFlow
|
||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
import net.corda.testing.DUMMY_NOTARY
|
||||||
import net.corda.testing.chooseIdentity
|
|
||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.node.NotarySpec
|
||||||
import net.corda.testing.performance.div
|
import net.corda.testing.performance.div
|
||||||
import net.corda.testing.performance.startPublishingFixedRateInjector
|
import net.corda.testing.performance.startPublishingFixedRateInjector
|
||||||
import net.corda.testing.performance.startReporter
|
import net.corda.testing.performance.startReporter
|
||||||
@ -102,26 +102,25 @@ class NodePerformanceTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `self pay rate`() {
|
fun `self pay rate`() {
|
||||||
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance")) {
|
val user = User("A", "A", setOf(startFlow<CashIssueFlow>(), startFlow<CashPaymentFlow>()))
|
||||||
val a = startNotaryNode(
|
driver(
|
||||||
DUMMY_NOTARY.name,
|
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name, rpcUsers = listOf(user))),
|
||||||
rpcUsers = listOf(User("A", "A", setOf(startFlow<CashIssueFlow>(), startFlow<CashPaymentFlow>())))
|
startNodesInProcess = true,
|
||||||
).getOrThrow()
|
extraCordappPackagesToScan = listOf("net.corda.finance")
|
||||||
a as NodeHandle.InProcess
|
) {
|
||||||
val metricRegistry = startReporter(shutdownManager, a.node.services.monitoringService.metrics)
|
val notary = defaultNotaryNode.getOrThrow() as NodeHandle.InProcess
|
||||||
a.rpcClientToNode().use("A", "A") { connection ->
|
val metricRegistry = startReporter(shutdownManager, notary.node.services.monitoringService.metrics)
|
||||||
val notary = connection.proxy.notaryIdentities().first()
|
notary.rpcClientToNode().use("A", "A") { connection ->
|
||||||
println("ISSUING")
|
println("ISSUING")
|
||||||
val doneFutures = (1..100).toList().parallelStream().map {
|
val doneFutures = (1..100).toList().parallelStream().map {
|
||||||
connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), notary).returnValue
|
connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), defaultNotaryIdentity).returnValue
|
||||||
}.toList()
|
}.toList()
|
||||||
doneFutures.transpose().get()
|
doneFutures.transpose().get()
|
||||||
println("STARTING PAYMENT")
|
println("STARTING PAYMENT")
|
||||||
startPublishingFixedRateInjector(metricRegistry, 8, 5.minutes, 100L / TimeUnit.SECONDS) {
|
startPublishingFixedRateInjector(metricRegistry, 8, 5.minutes, 100L / TimeUnit.SECONDS) {
|
||||||
connection.proxy.startFlow(::CashPaymentFlow, 1.DOLLARS, a.nodeInfo.chooseIdentity()).returnValue.get()
|
connection.proxy.startFlow(::CashPaymentFlow, 1.DOLLARS, defaultNotaryIdentity).returnValue.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,20 +13,16 @@ import net.corda.core.internal.div
|
|||||||
import net.corda.core.internal.toLedgerTransaction
|
import net.corda.core.internal.toLedgerTransaction
|
||||||
import net.corda.core.serialization.SerializationFactory
|
import net.corda.core.serialization.SerializationFactory
|
||||||
import net.corda.core.transactions.TransactionBuilder
|
import net.corda.core.transactions.TransactionBuilder
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.core.utilities.seconds
|
|
||||||
import net.corda.node.internal.cordapp.CordappLoader
|
import net.corda.node.internal.cordapp.CordappLoader
|
||||||
import net.corda.node.internal.cordapp.CordappProviderImpl
|
import net.corda.node.internal.cordapp.CordappProviderImpl
|
||||||
import net.corda.nodeapi.User
|
|
||||||
import net.corda.testing.DUMMY_BANK_A
|
import net.corda.testing.DUMMY_BANK_A
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
import net.corda.testing.DUMMY_NOTARY
|
||||||
import net.corda.testing.SerializationEnvironmentRule
|
import net.corda.testing.SerializationEnvironmentRule
|
||||||
import net.corda.testing.driver.DriverDSLExposedInterface
|
import net.corda.testing.driver.DriverDSLExposedInterface
|
||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import net.corda.testing.eventually
|
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -56,19 +52,15 @@ class AttachmentLoadingTests {
|
|||||||
|
|
||||||
val bankAName = CordaX500Name("BankA", "Zurich", "CH")
|
val bankAName = CordaX500Name("BankA", "Zurich", "CH")
|
||||||
val bankBName = CordaX500Name("BankB", "Zurich", "CH")
|
val bankBName = CordaX500Name("BankB", "Zurich", "CH")
|
||||||
val notaryName = CordaX500Name("Notary", "Zurich", "CH")
|
|
||||||
val flowInitiatorClass: Class<out FlowLogic<*>> =
|
val flowInitiatorClass: Class<out FlowLogic<*>> =
|
||||||
Class.forName("net.corda.finance.contracts.isolated.IsolatedDummyFlow\$Initiator", true, URLClassLoader(arrayOf(isolatedJAR)))
|
Class.forName("net.corda.finance.contracts.isolated.IsolatedDummyFlow\$Initiator", true, URLClassLoader(arrayOf(isolatedJAR)))
|
||||||
.asSubclass(FlowLogic::class.java)
|
.asSubclass(FlowLogic::class.java)
|
||||||
|
|
||||||
private fun DriverDSLExposedInterface.createNotaryAndTwoNodes(): List<NodeHandle> {
|
private fun DriverDSLExposedInterface.createTwoNodes(): List<NodeHandle> {
|
||||||
val adminUser = User("admin", "admin", permissions = setOf("ALL"))
|
return listOf(
|
||||||
val nodes = listOf(
|
startNode(providedName = bankAName),
|
||||||
startNotaryNode(providedName = notaryName, rpcUsers = listOf(adminUser), validating = false),
|
startNode(providedName = bankBName)
|
||||||
startNode(providedName = bankAName, rpcUsers = listOf(adminUser)),
|
).transpose().getOrThrow()
|
||||||
startNode(providedName = bankBName, rpcUsers = listOf(adminUser))
|
|
||||||
).transpose().getOrThrow() // Wait for all nodes to start up.
|
|
||||||
return nodes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun DriverDSLExposedInterface.installIsolatedCordappTo(nodeName: CordaX500Name) {
|
private fun DriverDSLExposedInterface.installIsolatedCordappTo(nodeName: CordaX500Name) {
|
||||||
@ -81,15 +73,6 @@ class AttachmentLoadingTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Due to cluster instability after nodes been started it may take some time to all the nodes to become available
|
|
||||||
// *and* discover each other to reliably communicate. Hence, eventual nature of the test.
|
|
||||||
// TODO: Remove this method and usages of it once NetworkMap service been re-worked
|
|
||||||
private fun eventuallyPassingTest(block: () -> Unit) {
|
|
||||||
eventually<Throwable, Unit>(30.seconds) {
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var services: Services
|
private lateinit var services: Services
|
||||||
@ -105,9 +88,8 @@ class AttachmentLoadingTests {
|
|||||||
val contractClass = appClassLoader.loadClass(ISOLATED_CONTRACT_ID).asSubclass(Contract::class.java)
|
val contractClass = appClassLoader.loadClass(ISOLATED_CONTRACT_ID).asSubclass(Contract::class.java)
|
||||||
val generateInitialMethod = contractClass.getDeclaredMethod("generateInitial", PartyAndReference::class.java, Integer.TYPE, Party::class.java)
|
val generateInitialMethod = contractClass.getDeclaredMethod("generateInitial", PartyAndReference::class.java, Integer.TYPE, Party::class.java)
|
||||||
val contract = contractClass.newInstance()
|
val contract = contractClass.newInstance()
|
||||||
val txBuilder = generateInitialMethod.invoke(contract, PartyAndReference(DUMMY_BANK_A, OpaqueBytes(kotlin.ByteArray(1))), 1, DUMMY_NOTARY) as TransactionBuilder
|
val txBuilder = generateInitialMethod.invoke(contract, DUMMY_BANK_A.ref(1), 1, DUMMY_NOTARY) as TransactionBuilder
|
||||||
val context = SerializationFactory.defaultFactory.defaultContext
|
val context = SerializationFactory.defaultFactory.defaultContext.withClassLoader(appClassLoader)
|
||||||
.withClassLoader(appClassLoader)
|
|
||||||
val ledgerTx = txBuilder.toLedgerTransaction(services, context)
|
val ledgerTx = txBuilder.toLedgerTransaction(services, context)
|
||||||
contract.verify(ledgerTx)
|
contract.verify(ledgerTx)
|
||||||
|
|
||||||
@ -121,11 +103,9 @@ class AttachmentLoadingTests {
|
|||||||
fun `test that attachments retrieved over the network are not used for code`() {
|
fun `test that attachments retrieved over the network are not used for code`() {
|
||||||
driver(initialiseSerialization = false) {
|
driver(initialiseSerialization = false) {
|
||||||
installIsolatedCordappTo(bankAName)
|
installIsolatedCordappTo(bankAName)
|
||||||
val (_, bankA, bankB) = createNotaryAndTwoNodes()
|
val (bankA, bankB) = createTwoNodes()
|
||||||
eventuallyPassingTest {
|
assertFailsWith<UnexpectedFlowEndException>("Party C=CH,L=Zurich,O=BankB rejected session request: Don't know net.corda.finance.contracts.isolated.IsolatedDummyFlow\$Initiator") {
|
||||||
assertFailsWith<UnexpectedFlowEndException>("Party C=CH,L=Zurich,O=BankB rejected session request: Don't know net.corda.finance.contracts.isolated.IsolatedDummyFlow\$Initiator") {
|
bankA.rpc.startFlowDynamic(flowInitiatorClass, bankB.nodeInfo.legalIdentities.first()).returnValue.getOrThrow()
|
||||||
bankA.rpc.startFlowDynamic(flowInitiatorClass, bankB.nodeInfo.legalIdentities.first()).returnValue.getOrThrow()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,10 +115,8 @@ class AttachmentLoadingTests {
|
|||||||
driver(initialiseSerialization = false) {
|
driver(initialiseSerialization = false) {
|
||||||
installIsolatedCordappTo(bankAName)
|
installIsolatedCordappTo(bankAName)
|
||||||
installIsolatedCordappTo(bankBName)
|
installIsolatedCordappTo(bankBName)
|
||||||
val (_, bankA, bankB) = createNotaryAndTwoNodes()
|
val (bankA, bankB) = createTwoNodes()
|
||||||
eventuallyPassingTest {
|
bankA.rpc.startFlowDynamic(flowInitiatorClass, bankB.nodeInfo.legalIdentities.first()).returnValue.getOrThrow()
|
||||||
bankA.rpc.startFlowDynamic(flowInitiatorClass, bankB.nodeInfo.legalIdentities.first()).returnValue.getOrThrow()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,60 +11,64 @@ import net.corda.core.utilities.getOrThrow
|
|||||||
import net.corda.finance.POUNDS
|
import net.corda.finance.POUNDS
|
||||||
import net.corda.finance.flows.CashIssueFlow
|
import net.corda.finance.flows.CashIssueFlow
|
||||||
import net.corda.finance.flows.CashPaymentFlow
|
import net.corda.finance.flows.CashPaymentFlow
|
||||||
import net.corda.node.services.Permissions.Companion.startFlow
|
|
||||||
import net.corda.node.services.Permissions.Companion.invokeRpc
|
import net.corda.node.services.Permissions.Companion.invokeRpc
|
||||||
import net.corda.node.services.transactions.RaftValidatingNotaryService
|
import net.corda.node.services.Permissions.Companion.startFlow
|
||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.*
|
import net.corda.testing.*
|
||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.node.ClusterSpec
|
||||||
|
import net.corda.testing.node.NotarySpec
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.test.assertEquals
|
|
||||||
|
|
||||||
class DistributedServiceTests {
|
class DistributedServiceTests {
|
||||||
lateinit var alice: NodeHandle
|
private lateinit var alice: NodeHandle
|
||||||
lateinit var notaries: List<NodeHandle.OutOfProcess>
|
private lateinit var notaryNodes: List<NodeHandle.OutOfProcess>
|
||||||
lateinit var aliceProxy: CordaRPCOps
|
private lateinit var aliceProxy: CordaRPCOps
|
||||||
lateinit var raftNotaryIdentity: Party
|
private lateinit var raftNotaryIdentity: Party
|
||||||
lateinit var notaryStateMachines: Observable<Pair<Party, StateMachineUpdate>>
|
private lateinit var notaryStateMachines: Observable<Pair<Party, StateMachineUpdate>>
|
||||||
private fun setup(runTest: () -> Unit) = driver(extraCordappPackagesToScan = listOf("net.corda.finance.contracts")) {
|
|
||||||
// Start Alice and 3 notaries in a RAFT cluster
|
private fun setup(testBlock: () -> Unit) {
|
||||||
val clusterSize = 3
|
|
||||||
val testUser = User("test", "test", permissions = setOf(
|
val testUser = User("test", "test", permissions = setOf(
|
||||||
startFlow<CashIssueFlow>(),
|
startFlow<CashIssueFlow>(),
|
||||||
startFlow<CashPaymentFlow>(),
|
startFlow<CashPaymentFlow>(),
|
||||||
invokeRpc(CordaRPCOps::nodeInfo),
|
invokeRpc(CordaRPCOps::nodeInfo),
|
||||||
invokeRpc(CordaRPCOps::stateMachinesFeed))
|
invokeRpc(CordaRPCOps::stateMachinesFeed))
|
||||||
)
|
)
|
||||||
val notariesFuture = startNotaryCluster(
|
|
||||||
DUMMY_NOTARY.name.copy(commonName = RaftValidatingNotaryService.id),
|
|
||||||
rpcUsers = listOf(testUser),
|
|
||||||
clusterSize = clusterSize
|
|
||||||
)
|
|
||||||
val aliceFuture = startNode(providedName = ALICE.name, rpcUsers = listOf(testUser))
|
|
||||||
|
|
||||||
alice = aliceFuture.get()
|
driver(
|
||||||
val (notaryIdentity, notaryNodes) = notariesFuture.get()
|
extraCordappPackagesToScan = listOf("net.corda.finance.contracts"),
|
||||||
raftNotaryIdentity = notaryIdentity
|
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name, rpcUsers = listOf(testUser), cluster = ClusterSpec.Raft(clusterSize = 3))))
|
||||||
notaries = notaryNodes.map { it as NodeHandle.OutOfProcess }
|
{
|
||||||
|
alice = startNode(providedName = ALICE.name, rpcUsers = listOf(testUser)).getOrThrow()
|
||||||
|
raftNotaryIdentity = defaultNotaryIdentity
|
||||||
|
notaryNodes = defaultNotaryHandle.nodeHandles.getOrThrow().map { it as NodeHandle.OutOfProcess }
|
||||||
|
|
||||||
assertEquals(notaries.size, clusterSize)
|
assertThat(notaryNodes).hasSize(3)
|
||||||
// Check that each notary has different identity as a node.
|
|
||||||
assertEquals(notaries.size, notaries.map { it.nodeInfo.chooseIdentity() }.toSet().size)
|
for (notaryNode in notaryNodes) {
|
||||||
// Connect to Alice and the notaries
|
assertThat(notaryNode.nodeInfo.legalIdentities).contains(raftNotaryIdentity)
|
||||||
fun connectRpc(node: NodeHandle): CordaRPCOps {
|
}
|
||||||
val client = node.rpcClientToNode()
|
|
||||||
return client.start("test", "test").proxy
|
// Check that each notary has different identity as a node.
|
||||||
|
assertThat(notaryNodes.flatMap { it.nodeInfo.legalIdentities - raftNotaryIdentity }.toSet()).hasSameSizeAs(notaryNodes)
|
||||||
|
|
||||||
|
// Connect to Alice and the notaries
|
||||||
|
fun connectRpc(node: NodeHandle): CordaRPCOps {
|
||||||
|
val client = node.rpcClientToNode()
|
||||||
|
return client.start("test", "test").proxy
|
||||||
|
}
|
||||||
|
aliceProxy = connectRpc(alice)
|
||||||
|
val rpcClientsToNotaries = notaryNodes.map(::connectRpc)
|
||||||
|
notaryStateMachines = Observable.from(rpcClientsToNotaries.map { proxy ->
|
||||||
|
proxy.stateMachinesFeed().updates.map { Pair(proxy.nodeInfo().chooseIdentity(), it) }
|
||||||
|
}).flatMap { it.onErrorResumeNext(Observable.empty()) }.bufferUntilSubscribed()
|
||||||
|
|
||||||
|
testBlock()
|
||||||
}
|
}
|
||||||
aliceProxy = connectRpc(alice)
|
|
||||||
val rpcClientsToNotaries = notaries.map(::connectRpc)
|
|
||||||
notaryStateMachines = Observable.from(rpcClientsToNotaries.map { proxy ->
|
|
||||||
proxy.stateMachinesFeed().updates.map { Pair(proxy.nodeInfo().chooseIdentity(), it) }
|
|
||||||
}).flatMap { it.onErrorResumeNext(Observable.empty()) }.bufferUntilSubscribed()
|
|
||||||
|
|
||||||
runTest()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Use a dummy distributed service rather than a Raft Notary Service as this test is only about Artemis' ability
|
// TODO Use a dummy distributed service rather than a Raft Notary Service as this test is only about Artemis' ability
|
||||||
@ -106,8 +110,8 @@ class DistributedServiceTests {
|
|||||||
paySelf(5.POUNDS)
|
paySelf(5.POUNDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now kill a notary
|
// Now kill a notary node
|
||||||
with(notaries[0].process) {
|
with(notaryNodes[0].process) {
|
||||||
destroy()
|
destroy()
|
||||||
waitFor()
|
waitFor()
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ import net.corda.testing.contracts.DummyContract
|
|||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import net.corda.testing.dummyCommand
|
import net.corda.testing.dummyCommand
|
||||||
|
import net.corda.testing.node.ClusterSpec
|
||||||
|
import net.corda.testing.node.NotarySpec
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
@ -28,13 +30,16 @@ class RaftNotaryServiceTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `detect double spend`() {
|
fun `detect double spend`() {
|
||||||
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.testing.contracts")) {
|
driver(
|
||||||
val (notaryParty) = startNotaryCluster(notaryName, 3).getOrThrow()
|
startNodesInProcess = true,
|
||||||
|
extraCordappPackagesToScan = listOf("net.corda.testing.contracts"),
|
||||||
|
notarySpecs = listOf(NotarySpec(notaryName, cluster = ClusterSpec.Raft(clusterSize = 3))))
|
||||||
|
{
|
||||||
val bankA = startNode(providedName = DUMMY_BANK_A.name).map { (it as NodeHandle.InProcess).node }.getOrThrow()
|
val bankA = startNode(providedName = DUMMY_BANK_A.name).map { (it as NodeHandle.InProcess).node }.getOrThrow()
|
||||||
|
|
||||||
val inputState = issueState(bankA, notaryParty)
|
val inputState = issueState(bankA, defaultNotaryIdentity)
|
||||||
|
|
||||||
val firstTxBuilder = TransactionBuilder(notaryParty)
|
val firstTxBuilder = TransactionBuilder(defaultNotaryIdentity)
|
||||||
.addInputState(inputState)
|
.addInputState(inputState)
|
||||||
.addCommand(dummyCommand(bankA.services.myInfo.chooseIdentity().owningKey))
|
.addCommand(dummyCommand(bankA.services.myInfo.chooseIdentity().owningKey))
|
||||||
val firstSpendTx = bankA.services.signInitialTransaction(firstTxBuilder)
|
val firstSpendTx = bankA.services.signInitialTransaction(firstTxBuilder)
|
||||||
@ -42,7 +47,7 @@ class RaftNotaryServiceTests {
|
|||||||
val firstSpend = bankA.services.startFlow(NotaryFlow.Client(firstSpendTx))
|
val firstSpend = bankA.services.startFlow(NotaryFlow.Client(firstSpendTx))
|
||||||
firstSpend.resultFuture.getOrThrow()
|
firstSpend.resultFuture.getOrThrow()
|
||||||
|
|
||||||
val secondSpendBuilder = TransactionBuilder(notaryParty).withItems(inputState).run {
|
val secondSpendBuilder = TransactionBuilder(defaultNotaryIdentity).withItems(inputState).run {
|
||||||
val dummyState = DummyContract.SingleOwnerState(0, bankA.info.chooseIdentity())
|
val dummyState = DummyContract.SingleOwnerState(0, bankA.info.chooseIdentity())
|
||||||
addOutputState(dummyState, DummyContract.PROGRAM_ID)
|
addOutputState(dummyState, DummyContract.PROGRAM_ID)
|
||||||
addCommand(dummyCommand(bankA.services.myInfo.chooseIdentity().owningKey))
|
addCommand(dummyCommand(bankA.services.myInfo.chooseIdentity().owningKey))
|
||||||
|
@ -8,11 +8,11 @@ import net.corda.core.messaging.startFlow
|
|||||||
import net.corda.core.transactions.TransactionBuilder
|
import net.corda.core.transactions.TransactionBuilder
|
||||||
import net.corda.testing.BOB
|
import net.corda.testing.BOB
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
import net.corda.testing.DUMMY_NOTARY
|
||||||
|
import net.corda.testing.aliceAndBob
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
import net.corda.testing.contracts.DummyState
|
import net.corda.testing.contracts.DummyState
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import net.corda.testing.dummyCommand
|
import net.corda.testing.dummyCommand
|
||||||
import net.corda.testing.notaryAliceAndBob
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ class LargeTransactionsTest {
|
|||||||
val bigFile3 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 2)
|
val bigFile3 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 2)
|
||||||
val bigFile4 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 3)
|
val bigFile4 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 3)
|
||||||
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.testing.contracts")) {
|
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.testing.contracts")) {
|
||||||
val (_, alice) = notaryAliceAndBob()
|
val (alice, _) = aliceAndBob()
|
||||||
alice.useRPC {
|
alice.useRPC {
|
||||||
val hash1 = it.uploadAttachment(bigFile1.inputStream)
|
val hash1 = it.uploadAttachment(bigFile1.inputStream)
|
||||||
val hash2 = it.uploadAttachment(bigFile2.inputStream)
|
val hash2 = it.uploadAttachment(bigFile2.inputStream)
|
||||||
|
@ -21,6 +21,8 @@ import net.corda.testing.chooseIdentity
|
|||||||
import net.corda.testing.driver.DriverDSLExposedInterface
|
import net.corda.testing.driver.DriverDSLExposedInterface
|
||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.node.ClusterSpec
|
||||||
|
import net.corda.testing.node.NotarySpec
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -35,16 +37,14 @@ class P2PMessagingTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `communicating with a distributed service which we're part of`() {
|
fun `communicating with a distributed service which we're part of`() {
|
||||||
driver(startNodesInProcess = true) {
|
startDriverWithDistributedService { distributedService ->
|
||||||
val distributedService = startDistributedService()
|
|
||||||
assertAllNodesAreUsed(distributedService, DISTRIBUTED_SERVICE_NAME, distributedService[0])
|
assertAllNodesAreUsed(distributedService, DISTRIBUTED_SERVICE_NAME, distributedService[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `distributed service requests are retried if one of the nodes in the cluster goes down without sending a response`() {
|
fun `distributed service requests are retried if one of the nodes in the cluster goes down without sending a response`() {
|
||||||
driver(startNodesInProcess = true) {
|
startDriverWithDistributedService { distributedServiceNodes ->
|
||||||
val distributedServiceNodes = startDistributedService()
|
|
||||||
val alice = startAlice()
|
val alice = startAlice()
|
||||||
val serviceAddress = alice.services.networkMapCache.run {
|
val serviceAddress = alice.services.networkMapCache.run {
|
||||||
val notaryParty = notaryIdentities.randomOrNull()!!
|
val notaryParty = notaryIdentities.randomOrNull()!!
|
||||||
@ -77,8 +77,7 @@ class P2PMessagingTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `distributed service request retries are persisted across client node restarts`() {
|
fun `distributed service request retries are persisted across client node restarts`() {
|
||||||
driver(startNodesInProcess = true) {
|
startDriverWithDistributedService { distributedServiceNodes ->
|
||||||
val distributedServiceNodes = startDistributedService()
|
|
||||||
val alice = startAlice()
|
val alice = startAlice()
|
||||||
val serviceAddress = alice.services.networkMapCache.run {
|
val serviceAddress = alice.services.networkMapCache.run {
|
||||||
val notaryParty = notaryIdentities.randomOrNull()!!
|
val notaryParty = notaryIdentities.randomOrNull()!!
|
||||||
@ -117,11 +116,10 @@ class P2PMessagingTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun DriverDSLExposedInterface.startDistributedService(): List<StartedNode<Node>> {
|
private fun startDriverWithDistributedService(dsl: DriverDSLExposedInterface.(List<StartedNode<Node>>) -> Unit) {
|
||||||
return startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2)
|
driver(startNodesInProcess = true, notarySpecs = listOf(NotarySpec(DISTRIBUTED_SERVICE_NAME, cluster = ClusterSpec.Raft(clusterSize = 2)))) {
|
||||||
.getOrThrow()
|
dsl(defaultNotaryHandle.nodeHandles.getOrThrow().map { (it as NodeHandle.InProcess).node })
|
||||||
.second
|
}
|
||||||
.map { (it as NodeHandle.InProcess).node }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun DriverDSLExposedInterface.startAlice(): StartedNode<Node> {
|
private fun DriverDSLExposedInterface.startAlice(): StartedNode<Node> {
|
||||||
|
@ -17,10 +17,9 @@ import net.corda.core.transactions.SignedTransaction
|
|||||||
import net.corda.core.transactions.TransactionBuilder
|
import net.corda.core.transactions.TransactionBuilder
|
||||||
import net.corda.core.utilities.ProgressTracker
|
import net.corda.core.utilities.ProgressTracker
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.node.services.Permissions.Companion.startFlow
|
|
||||||
import net.corda.node.services.Permissions.Companion.invokeRpc
|
import net.corda.node.services.Permissions.Companion.invokeRpc
|
||||||
|
import net.corda.node.services.Permissions.Companion.startFlow
|
||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.chooseIdentity
|
import net.corda.testing.chooseIdentity
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import org.junit.Assume.assumeFalse
|
import org.junit.Assume.assumeFalse
|
||||||
@ -43,7 +42,6 @@ class NodeStatePersistenceTests {
|
|||||||
val message = Message("Hello world!")
|
val message = Message("Hello world!")
|
||||||
driver(isDebug = true, startNodesInProcess = isQuasarAgentSpecified()) {
|
driver(isDebug = true, startNodesInProcess = isQuasarAgentSpecified()) {
|
||||||
val nodeName = {
|
val nodeName = {
|
||||||
startNotaryNode(DUMMY_NOTARY.name, validating = false).getOrThrow()
|
|
||||||
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
|
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
|
||||||
val nodeName = nodeHandle.nodeInfo.chooseIdentity().name
|
val nodeName = nodeHandle.nodeInfo.chooseIdentity().name
|
||||||
nodeHandle.rpcClientToNode().start(user.username, user.password).use {
|
nodeHandle.rpcClientToNode().start(user.username, user.password).use {
|
||||||
|
@ -31,6 +31,7 @@ import java.security.PublicKey
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.annotation.concurrent.ThreadSafe
|
import javax.annotation.concurrent.ThreadSafe
|
||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
|
import kotlin.collections.HashSet
|
||||||
|
|
||||||
class NetworkMapCacheImpl(
|
class NetworkMapCacheImpl(
|
||||||
networkMapCacheBase: NetworkMapCacheBaseInternal,
|
networkMapCacheBase: NetworkMapCacheBaseInternal,
|
||||||
@ -85,7 +86,7 @@ open class PersistentNetworkMapCache(
|
|||||||
override val loadDBSuccess get() = _loadDBSuccess
|
override val loadDBSuccess get() = _loadDBSuccess
|
||||||
|
|
||||||
override val notaryIdentities: List<Party> = notaries.map { it.identity }
|
override val notaryIdentities: List<Party> = notaries.map { it.identity }
|
||||||
private val validatingNotaries = notaries.mapNotNull { if (it.validating) it.identity else null }
|
private val validatingNotaries = notaries.mapNotNullTo(HashSet()) { if (it.validating) it.identity else null }
|
||||||
|
|
||||||
private val nodeInfoSerializer = NodeInfoWatcher(configuration.baseDirectory,
|
private val nodeInfoSerializer = NodeInfoWatcher(configuration.baseDirectory,
|
||||||
configuration.additionalNodeInfoPollingFrequencyMsec)
|
configuration.additionalNodeInfoPollingFrequencyMsec)
|
||||||
|
@ -50,14 +50,12 @@ import kotlin.test.assertNull
|
|||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class CordaRPCOpsImplTest {
|
class CordaRPCOpsImplTest {
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val testJar = "net/corda/node/testing/test.jar"
|
val testJar = "net/corda/node/testing/test.jar"
|
||||||
}
|
}
|
||||||
|
|
||||||
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 notaryNode: StartedNode<MockNode>
|
|
||||||
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>
|
||||||
@ -69,7 +67,6 @@ 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"))
|
||||||
notaryNode = mockNet.createNotaryNode(validating = false)
|
|
||||||
aliceNode = mockNet.createNode()
|
aliceNode = mockNet.createNode()
|
||||||
rpc = SecureCordaRPCOps(aliceNode.services, aliceNode.smm, aliceNode.database, aliceNode.services)
|
rpc = SecureCordaRPCOps(aliceNode.services, aliceNode.smm, aliceNode.database, aliceNode.services)
|
||||||
CURRENT_RPC_CONTEXT.set(RpcContext(user))
|
CURRENT_RPC_CONTEXT.set(RpcContext(user))
|
||||||
|
@ -74,14 +74,12 @@ class TestCordaService2(val appServiceHub: AppServiceHub): SingletonSerializeAsT
|
|||||||
class LegacyCordaService(@Suppress("UNUSED_PARAMETER") simpleServiceHub: ServiceHub) : SingletonSerializeAsToken()
|
class LegacyCordaService(@Suppress("UNUSED_PARAMETER") simpleServiceHub: ServiceHub) : SingletonSerializeAsToken()
|
||||||
|
|
||||||
class CordaServiceTest {
|
class CordaServiceTest {
|
||||||
lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
|
private lateinit var nodeA: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var nodeA: StartedNode<MockNetwork.MockNode>
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun start() {
|
fun start() {
|
||||||
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.node.internal","net.corda.finance"))
|
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.node.internal","net.corda.finance"))
|
||||||
notaryNode = mockNet.createNotaryNode()
|
|
||||||
nodeA = mockNet.createNode()
|
nodeA = mockNet.createNode()
|
||||||
mockNet.startNodes()
|
mockNet.startNodes()
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ import kotlin.test.assertTrue
|
|||||||
* We assume that Alice and Bob already found each other via some market, and have agreed the details already.
|
* We assume that Alice and Bob already found each other via some market, and have agreed the details already.
|
||||||
*/
|
*/
|
||||||
@RunWith(Parameterized::class)
|
@RunWith(Parameterized::class)
|
||||||
class TwoPartyTradeFlowTests(val anonymous: Boolean) {
|
class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||||
companion object {
|
companion object {
|
||||||
private val cordappPackages = listOf("net.corda.finance.contracts")
|
private val cordappPackages = listOf("net.corda.finance.contracts")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@ -93,7 +93,7 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) {
|
|||||||
// allow interruption half way through.
|
// allow interruption half way through.
|
||||||
mockNet = MockNetwork(threadPerNode = true, cordappPackages = cordappPackages)
|
mockNet = MockNetwork(threadPerNode = true, cordappPackages = cordappPackages)
|
||||||
ledger(MockServices(cordappPackages), initialiseSerialization = false) {
|
ledger(MockServices(cordappPackages), initialiseSerialization = false) {
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
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 bankNode = mockNet.createPartyNode(BOC_NAME)
|
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
||||||
@ -143,7 +143,7 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) {
|
|||||||
fun `trade cash for commercial paper fails using soft locking`() {
|
fun `trade cash for commercial paper fails using soft locking`() {
|
||||||
mockNet = MockNetwork(threadPerNode = true, cordappPackages = cordappPackages)
|
mockNet = MockNetwork(threadPerNode = true, cordappPackages = cordappPackages)
|
||||||
ledger(MockServices(cordappPackages), initialiseSerialization = false) {
|
ledger(MockServices(cordappPackages), initialiseSerialization = false) {
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
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 bankNode = mockNet.createPartyNode(BOC_NAME)
|
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
||||||
@ -199,7 +199,7 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) {
|
|||||||
fun `shutdown and restore`() {
|
fun `shutdown and restore`() {
|
||||||
mockNet = MockNetwork(cordappPackages = cordappPackages)
|
mockNet = MockNetwork(cordappPackages = cordappPackages)
|
||||||
ledger(MockServices(cordappPackages), initialiseSerialization = false) {
|
ledger(MockServices(cordappPackages), initialiseSerialization = false) {
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
val notaryNode = mockNet.defaultNotaryNode
|
||||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||||
var bobNode = mockNet.createPartyNode(BOB_NAME)
|
var bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||||
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
||||||
@ -292,7 +292,8 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) {
|
|||||||
|
|
||||||
// Creates a mock node with an overridden storage service that uses a RecordingMap, that lets us test the order
|
// Creates a mock node with an overridden storage service that uses a RecordingMap, that lets us test the order
|
||||||
// of gets and puts.
|
// of gets and puts.
|
||||||
private fun makeNodeWithTracking(name: CordaX500Name): StartedNode<MockNetwork.MockNode> {
|
private fun makeNodeWithTracking(
|
||||||
|
name: CordaX500Name): StartedNode<MockNetwork.MockNode> {
|
||||||
// Create a node in the mock network ...
|
// Create a node in the mock network ...
|
||||||
return mockNet.createNode(MockNodeParameters(legalName = name), nodeFactory = { args ->
|
return mockNet.createNode(MockNodeParameters(legalName = name), nodeFactory = { args ->
|
||||||
object : MockNetwork.MockNode(args) {
|
object : MockNetwork.MockNode(args) {
|
||||||
@ -307,7 +308,7 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) {
|
|||||||
@Test
|
@Test
|
||||||
fun `check dependencies of sale asset are resolved`() {
|
fun `check dependencies of sale asset are resolved`() {
|
||||||
mockNet = MockNetwork(cordappPackages = cordappPackages)
|
mockNet = MockNetwork(cordappPackages = cordappPackages)
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
val notaryNode = mockNet.defaultNotaryNode
|
||||||
val aliceNode = makeNodeWithTracking(ALICE_NAME)
|
val aliceNode = makeNodeWithTracking(ALICE_NAME)
|
||||||
val bobNode = makeNodeWithTracking(BOB_NAME)
|
val bobNode = makeNodeWithTracking(BOB_NAME)
|
||||||
val bankNode = makeNodeWithTracking(BOC_NAME)
|
val bankNode = makeNodeWithTracking(BOC_NAME)
|
||||||
@ -413,7 +414,7 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) {
|
|||||||
@Test
|
@Test
|
||||||
fun `track works`() {
|
fun `track works`() {
|
||||||
mockNet = MockNetwork(cordappPackages = cordappPackages)
|
mockNet = MockNetwork(cordappPackages = cordappPackages)
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
val notaryNode = mockNet.defaultNotaryNode
|
||||||
val aliceNode = makeNodeWithTracking(ALICE_NAME)
|
val aliceNode = makeNodeWithTracking(ALICE_NAME)
|
||||||
val bobNode = makeNodeWithTracking(BOB_NAME)
|
val bobNode = makeNodeWithTracking(BOB_NAME)
|
||||||
val bankNode = makeNodeWithTracking(BOC_NAME)
|
val bankNode = makeNodeWithTracking(BOC_NAME)
|
||||||
@ -568,7 +569,7 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) {
|
|||||||
aliceError: Boolean,
|
aliceError: Boolean,
|
||||||
expectedMessageSubstring: String
|
expectedMessageSubstring: String
|
||||||
) {
|
) {
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
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 bankNode = mockNet.createPartyNode(BOC_NAME)
|
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package net.corda.node.services
|
package net.corda.node.services
|
||||||
|
|
||||||
import com.nhaarman.mockito_kotlin.doReturn
|
|
||||||
import com.nhaarman.mockito_kotlin.whenever
|
|
||||||
import net.corda.core.contracts.*
|
import net.corda.core.contracts.*
|
||||||
import net.corda.core.crypto.generateKeyPair
|
import net.corda.core.crypto.generateKeyPair
|
||||||
import net.corda.core.flows.NotaryChangeFlow
|
import net.corda.core.flows.NotaryChangeFlow
|
||||||
@ -15,14 +13,10 @@ import net.corda.core.transactions.WireTransaction
|
|||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
import net.corda.node.internal.StartedNode
|
import net.corda.node.internal.StartedNode
|
||||||
import net.corda.node.services.config.NotaryConfig
|
import net.corda.testing.*
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.chooseIdentity
|
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
import net.corda.testing.dummyCommand
|
|
||||||
import net.corda.testing.getTestPartyAndCertificate
|
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
import net.corda.testing.node.MockNodeParameters
|
import net.corda.testing.node.MockNetwork.NotarySpec
|
||||||
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
|
||||||
@ -42,23 +36,17 @@ class NotaryChangeTests {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts"))
|
val oldNotaryName = DUMMY_REGULATOR.name
|
||||||
val (oldNotaryNode, newNotaryNode) = listOf(
|
mockNet = MockNetwork(
|
||||||
createUnstartedNotary(DUMMY_NOTARY.name),
|
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name), NotarySpec(oldNotaryName)),
|
||||||
createUnstartedNotary(DUMMY_NOTARY.name.copy(organisation = "Dummy Notary 2"))
|
cordappPackages = listOf("net.corda.testing.contracts")
|
||||||
).map { it.start() }
|
)
|
||||||
this.oldNotaryNode = oldNotaryNode
|
|
||||||
clientNodeA = mockNet.createNode()
|
clientNodeA = mockNet.createNode()
|
||||||
clientNodeB = mockNet.createNode()
|
clientNodeB = mockNet.createNode()
|
||||||
oldNotaryParty = newNotaryNode.services.networkMapCache.getNotary(DUMMY_NOTARY.name)!!
|
oldNotaryNode = mockNet.notaryNodes[1]
|
||||||
newNotaryParty = newNotaryNode.services.networkMapCache.getNotary(DUMMY_NOTARY.name.copy(organisation = "Dummy Notary 2"))!!
|
mockNet.runNetwork() // Clear network map registration messages
|
||||||
}
|
newNotaryParty = clientNodeA.services.networkMapCache.getNotary(DUMMY_NOTARY.name)!!
|
||||||
|
oldNotaryParty = clientNodeA.services.networkMapCache.getNotary(oldNotaryName)!!
|
||||||
private fun createUnstartedNotary(name: CordaX500Name): MockNetwork.MockNode {
|
|
||||||
return mockNet.createUnstartedNode(MockNodeParameters(
|
|
||||||
legalName = name,
|
|
||||||
configOverrides = { doReturn(NotaryConfig(validating = true)).whenever(it).notary }
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -35,7 +35,6 @@ class ScheduledFlowTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lateinit var mockNet: MockNetwork
|
lateinit var mockNet: MockNetwork
|
||||||
lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
|
|
||||||
lateinit var nodeA: StartedNode<MockNetwork.MockNode>
|
lateinit var nodeA: StartedNode<MockNetwork.MockNode>
|
||||||
lateinit var nodeB: StartedNode<MockNetwork.MockNode>
|
lateinit var nodeB: StartedNode<MockNetwork.MockNode>
|
||||||
|
|
||||||
@ -94,7 +93,6 @@ 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"))
|
||||||
notaryNode = mockNet.createNotaryNode()
|
|
||||||
val a = mockNet.createUnstartedNode()
|
val a = mockNet.createUnstartedNode()
|
||||||
val b = mockNet.createUnstartedNode()
|
val b = mockNet.createUnstartedNode()
|
||||||
|
|
||||||
|
@ -38,13 +38,13 @@ class NetworkMapCacheTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `getNodeByLegalIdentity`() {
|
fun `getNodeByLegalIdentity`() {
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
|
||||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||||
val notaryCache: NetworkMapCache = notaryNode.services.networkMapCache
|
val bobNode = mockNet.createPartyNode(BOB.name)
|
||||||
|
val bobCache: NetworkMapCache = bobNode.services.networkMapCache
|
||||||
val expected = aliceNode.info
|
val expected = aliceNode.info
|
||||||
|
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
val actual = notaryNode.database.transaction { notaryCache.getNodeByLegalIdentity(aliceNode.info.chooseIdentity()) }
|
val actual = bobNode.database.transaction { bobCache.getNodeByLegalIdentity(aliceNode.info.chooseIdentity()) }
|
||||||
assertEquals(expected, actual)
|
assertEquals(expected, actual)
|
||||||
|
|
||||||
// TODO: Should have a test case with anonymous lookup
|
// TODO: Should have a test case with anonymous lookup
|
||||||
@ -52,30 +52,30 @@ class NetworkMapCacheTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `getPeerByLegalName`() {
|
fun `getPeerByLegalName`() {
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
|
||||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||||
val notaryCache: NetworkMapCache = notaryNode.services.networkMapCache
|
val bobNode = mockNet.createPartyNode(BOB.name)
|
||||||
|
val bobCache: NetworkMapCache = bobNode.services.networkMapCache
|
||||||
val expected = aliceNode.info.legalIdentities.single()
|
val expected = aliceNode.info.legalIdentities.single()
|
||||||
|
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
val actual = notaryNode.database.transaction { notaryCache.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 notaryNode = mockNet.createNotaryNode()
|
|
||||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||||
val notaryLegalIdentity = notaryNode.info.chooseIdentity()
|
val bobNode = mockNet.createPartyNode(BOB.name)
|
||||||
|
val bobLegalIdentity = bobNode.info.chooseIdentity()
|
||||||
val alice = aliceNode.info.chooseIdentity()
|
val alice = aliceNode.info.chooseIdentity()
|
||||||
val notaryCache = notaryNode.services.networkMapCache
|
val bobCache = bobNode.services.networkMapCache
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
notaryNode.database.transaction {
|
bobNode.database.transaction {
|
||||||
assertThat(notaryCache.getNodeByLegalIdentity(alice) != null)
|
assertThat(bobCache.getNodeByLegalIdentity(alice) != null)
|
||||||
notaryCache.removeNode(aliceNode.info)
|
bobCache.removeNode(aliceNode.info)
|
||||||
assertThat(notaryCache.getNodeByLegalIdentity(alice) == null)
|
assertThat(bobCache.getNodeByLegalIdentity(alice) == null)
|
||||||
assertThat(notaryCache.getNodeByLegalIdentity(notaryLegalIdentity) != null)
|
assertThat(bobCache.getNodeByLegalIdentity(bobLegalIdentity) != null)
|
||||||
assertThat(notaryCache.getNodeByLegalName(alice.name) == null)
|
assertThat(bobCache.getNodeByLegalName(alice.name) == null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,7 @@ class NodeSchemaServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `auto scanning of custom schemas for testing with Driver`() {
|
fun `auto scanning of custom schemas for testing with Driver`() {
|
||||||
driver(startNodesInProcess = true) {
|
driver(startNodesInProcess = true) {
|
||||||
val node = startNode()
|
val result = defaultNotaryNode.getOrThrow().rpc.startFlow(::MappedSchemasFlow)
|
||||||
val nodeHandle = node.getOrThrow()
|
|
||||||
val result = nodeHandle.rpc.startFlow(::MappedSchemasFlow)
|
|
||||||
val mappedSchemas = result.returnValue.getOrThrow()
|
val mappedSchemas = result.returnValue.getOrThrow()
|
||||||
assertTrue(mappedSchemas.contains(TestSchema.name))
|
assertTrue(mappedSchemas.contains(TestSchema.name))
|
||||||
}
|
}
|
||||||
@ -54,11 +52,12 @@ class NodeSchemaServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `custom schemas are loaded eagerly`() {
|
fun `custom schemas are loaded eagerly`() {
|
||||||
val expected = setOf("PARENTS", "CHILDREN")
|
val expected = setOf("PARENTS", "CHILDREN")
|
||||||
assertEquals<Set<*>>(expected, driver {
|
val tables = driver(startNodesInProcess = true) {
|
||||||
(startNode(startInSameProcess = true).getOrThrow() as NodeHandle.InProcess).node.database.transaction {
|
(defaultNotaryNode.getOrThrow() as NodeHandle.InProcess).node.database.transaction {
|
||||||
session.createNativeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES").list()
|
session.createNativeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES").list()
|
||||||
}
|
}
|
||||||
}.toMutableSet().apply { retainAll(expected) })
|
}
|
||||||
|
assertEquals<Set<*>>(expected, tables.toMutableSet().apply { retainAll(expected) })
|
||||||
}
|
}
|
||||||
|
|
||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
|
@ -74,8 +74,8 @@ class FlowFrameworkTests {
|
|||||||
fun start() {
|
fun start() {
|
||||||
mockNet = MockNetwork(
|
mockNet = MockNetwork(
|
||||||
servicePeerAllocationStrategy = RoundRobin(),
|
servicePeerAllocationStrategy = RoundRobin(),
|
||||||
cordappPackages = listOf("net.corda.finance.contracts", "net.corda.testing.contracts"))
|
cordappPackages = listOf("net.corda.finance.contracts", "net.corda.testing.contracts")
|
||||||
val notary = mockNet.createNotaryNode()
|
)
|
||||||
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
|
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
|
||||||
bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
|
bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ class FlowFrameworkTests {
|
|||||||
// Extract identities
|
// Extract identities
|
||||||
alice = aliceNode.info.singleIdentity()
|
alice = aliceNode.info.singleIdentity()
|
||||||
bob = bobNode.info.singleIdentity()
|
bob = bobNode.info.singleIdentity()
|
||||||
notaryIdentity = notary.services.getDefaultNotary()
|
notaryIdentity = aliceNode.services.getDefaultNotary()
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -14,10 +14,13 @@ import net.corda.core.transactions.TransactionBuilder
|
|||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
import net.corda.node.services.api.StartedNodeServices
|
import net.corda.node.services.api.StartedNodeServices
|
||||||
import net.corda.testing.*
|
import net.corda.testing.ALICE_NAME
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
|
import net.corda.testing.dummyCommand
|
||||||
|
import net.corda.testing.getDefaultNotary
|
||||||
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.Before
|
import org.junit.Before
|
||||||
@ -28,20 +31,19 @@ import kotlin.test.assertEquals
|
|||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
class NotaryServiceTests {
|
class NotaryServiceTests {
|
||||||
lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
lateinit var notaryServices: StartedNodeServices
|
private lateinit var notaryServices: StartedNodeServices
|
||||||
lateinit var aliceServices: StartedNodeServices
|
private lateinit var aliceServices: StartedNodeServices
|
||||||
lateinit var notary: Party
|
private lateinit var notary: Party
|
||||||
lateinit var alice: Party
|
private lateinit var alice: Party
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts"))
|
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts"))
|
||||||
val notaryNode = mockNet.createNotaryNode(validating = false)
|
|
||||||
aliceServices = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME)).services
|
aliceServices = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME)).services
|
||||||
mockNet.runNetwork() // Clear network map registration messages
|
mockNet.runNetwork() // Clear network map registration messages
|
||||||
notaryServices = notaryNode.services
|
notaryServices = mockNet.defaultNotaryNode.services //TODO get rid of that
|
||||||
notary = notaryServices.getDefaultNotary()
|
notary = aliceServices.getDefaultNotary()
|
||||||
alice = aliceServices.myInfo.singleIdentity()
|
alice = aliceServices.myInfo.singleIdentity()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +157,7 @@ class NotaryServiceTests {
|
|||||||
return future
|
return future
|
||||||
}
|
}
|
||||||
|
|
||||||
fun issueState(services: ServiceHub, identity: Party): StateAndRef<*> {
|
private fun issueState(services: ServiceHub, identity: Party): StateAndRef<*> {
|
||||||
val tx = DummyContract.generateInitial(Random().nextInt(), notary, identity.ref(0))
|
val tx = DummyContract.generateInitial(Random().nextInt(), notary, identity.ref(0))
|
||||||
val signedByNode = services.signInitialTransaction(tx)
|
val signedByNode = services.signInitialTransaction(tx)
|
||||||
val stx = notaryServices.addSignature(signedByNode, notary.owningKey)
|
val stx = notaryServices.addSignature(signedByNode, notary.owningKey)
|
||||||
|
@ -15,10 +15,13 @@ import net.corda.core.transactions.TransactionBuilder
|
|||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.node.services.api.StartedNodeServices
|
import net.corda.node.services.api.StartedNodeServices
|
||||||
import net.corda.node.services.issueInvalidState
|
import net.corda.node.services.issueInvalidState
|
||||||
import net.corda.testing.*
|
import net.corda.testing.ALICE_NAME
|
||||||
|
import net.corda.testing.MEGA_CORP_KEY
|
||||||
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.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.Before
|
import org.junit.Before
|
||||||
@ -28,21 +31,20 @@ import kotlin.test.assertEquals
|
|||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
class ValidatingNotaryServiceTests {
|
class ValidatingNotaryServiceTests {
|
||||||
lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
lateinit var notaryServices: StartedNodeServices
|
private lateinit var notaryServices: StartedNodeServices
|
||||||
lateinit var aliceServices: StartedNodeServices
|
private lateinit var aliceServices: StartedNodeServices
|
||||||
lateinit var notary: Party
|
private lateinit var notary: Party
|
||||||
lateinit var alice: Party
|
private lateinit var alice: Party
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts"))
|
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts"))
|
||||||
val notaryNode = mockNet.createNotaryNode()
|
|
||||||
val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
|
val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
|
||||||
mockNet.runNetwork() // Clear network map registration messages
|
mockNet.runNetwork() // Clear network map registration messages
|
||||||
notaryServices = notaryNode.services
|
notaryServices = mockNet.defaultNotaryNode.services
|
||||||
aliceServices = aliceNode.services
|
aliceServices = aliceNode.services
|
||||||
notary = notaryServices.getDefaultNotary()
|
notary = mockNet.defaultNotaryIdentity
|
||||||
alice = aliceNode.info.singleIdentity()
|
alice = aliceNode.info.singleIdentity()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +99,7 @@ class ValidatingNotaryServiceTests {
|
|||||||
return future
|
return future
|
||||||
}
|
}
|
||||||
|
|
||||||
fun issueState(serviceHub: ServiceHub, identity: Party): StateAndRef<*> {
|
private fun issueState(serviceHub: ServiceHub, identity: Party): StateAndRef<*> {
|
||||||
val tx = DummyContract.generateInitial(Random().nextInt(), notary, identity.ref(0))
|
val tx = DummyContract.generateInitial(Random().nextInt(), notary, identity.ref(0))
|
||||||
val signedByNode = serviceHub.signInitialTransaction(tx)
|
val signedByNode = serviceHub.signInitialTransaction(tx)
|
||||||
val stx = notaryServices.addSignature(signedByNode, notary.owningKey)
|
val stx = notaryServices.addSignature(signedByNode, notary.owningKey)
|
||||||
|
@ -7,7 +7,6 @@ import net.corda.node.services.Permissions.Companion.startFlow
|
|||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.DUMMY_BANK_A
|
import net.corda.testing.DUMMY_BANK_A
|
||||||
import net.corda.testing.DUMMY_BANK_B
|
import net.corda.testing.DUMMY_BANK_B
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.PortAllocation
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -27,11 +26,10 @@ class AttachmentDemoTest {
|
|||||||
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name),
|
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name),
|
||||||
invokeRpc(CordaRPCOps::internalVerifiedTransactionsFeed)
|
invokeRpc(CordaRPCOps::internalVerifiedTransactionsFeed)
|
||||||
)))
|
)))
|
||||||
val (_, nodeA, nodeB) = listOf(
|
val (nodeA, nodeB) = listOf(
|
||||||
startNotaryNode(DUMMY_NOTARY.name, validating = false),
|
|
||||||
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = demoUser, maximumHeapSize = "1g"),
|
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = demoUser, maximumHeapSize = "1g"),
|
||||||
startNode(providedName = DUMMY_BANK_B.name, rpcUsers = demoUser, maximumHeapSize = "1g"))
|
startNode(providedName = DUMMY_BANK_B.name, rpcUsers = demoUser, maximumHeapSize = "1g")
|
||||||
.map { it.getOrThrow() }
|
).map { it.getOrThrow() }
|
||||||
startWebserver(nodeB).getOrThrow()
|
startWebserver(nodeB).getOrThrow()
|
||||||
|
|
||||||
val senderThread = supplyAsync {
|
val senderThread = supplyAsync {
|
||||||
|
@ -4,7 +4,6 @@ import net.corda.core.internal.div
|
|||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.DUMMY_BANK_A
|
import net.corda.testing.DUMMY_BANK_A
|
||||||
import net.corda.testing.DUMMY_BANK_B
|
import net.corda.testing.DUMMY_BANK_B
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,7 +13,6 @@ import net.corda.testing.driver.driver
|
|||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val demoUser = listOf(User("demo", "demo", setOf("StartFlow.net.corda.flows.FinalityFlow")))
|
val demoUser = listOf(User("demo", "demo", setOf("StartFlow.net.corda.flows.FinalityFlow")))
|
||||||
driver(isDebug = true, driverDirectory = "build" / "attachment-demo-nodes") {
|
driver(isDebug = true, driverDirectory = "build" / "attachment-demo-nodes") {
|
||||||
startNotaryNode(DUMMY_NOTARY.name, validating = false)
|
|
||||||
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = demoUser)
|
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = demoUser)
|
||||||
startNode(providedName = DUMMY_BANK_B.name, rpcUsers = demoUser)
|
startNode(providedName = DUMMY_BANK_B.name, rpcUsers = demoUser)
|
||||||
waitForAllNodesToFinish()
|
waitForAllNodesToFinish()
|
||||||
|
@ -2,10 +2,8 @@ package net.corda.bank
|
|||||||
|
|
||||||
import net.corda.bank.api.BankOfCordaClientApi
|
import net.corda.bank.api.BankOfCordaClientApi
|
||||||
import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams
|
import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams
|
||||||
import net.corda.core.internal.concurrent.transpose
|
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.testing.BOC
|
import net.corda.testing.BOC
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -13,14 +11,13 @@ import kotlin.test.assertTrue
|
|||||||
class BankOfCordaHttpAPITest {
|
class BankOfCordaHttpAPITest {
|
||||||
@Test
|
@Test
|
||||||
fun `issuer flow via Http`() {
|
fun `issuer flow via Http`() {
|
||||||
driver(isDebug = true, extraCordappPackagesToScan = listOf("net.corda.finance")) {
|
driver(extraCordappPackagesToScan = listOf("net.corda.finance"), isDebug = true) {
|
||||||
val (_, bocNode) = listOf(
|
val (bocNode) = listOf(
|
||||||
startNotaryNode(providedName = DUMMY_NOTARY.name),
|
|
||||||
startNode(providedName = BOC.name),
|
startNode(providedName = BOC.name),
|
||||||
startNode(providedName = BIGCORP_LEGAL_NAME)
|
startNode(providedName = BIGCORP_LEGAL_NAME)
|
||||||
).transpose().getOrThrow()
|
).map { it.getOrThrow() }
|
||||||
val bocApiAddress = startWebserver(bocNode).getOrThrow().listenAddress
|
val bocApiAddress = startWebserver(bocNode).getOrThrow().listenAddress
|
||||||
val issueRequestParams = IssueRequestParams(1000, "USD", BIGCORP_LEGAL_NAME, "1", BOC.name, DUMMY_NOTARY.name)
|
val issueRequestParams = IssueRequestParams(1000, "USD", BIGCORP_LEGAL_NAME, "1", BOC.name, defaultNotaryIdentity.name)
|
||||||
assertTrue(BankOfCordaClientApi(bocApiAddress).requestWebIssue(issueRequestParams))
|
assertTrue(BankOfCordaClientApi(bocApiAddress).requestWebIssue(issueRequestParams))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,12 @@ class BankOfCordaRPCClientTest {
|
|||||||
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name),
|
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name),
|
||||||
invokeRpc(CordaRPCOps::notaryIdentities)
|
invokeRpc(CordaRPCOps::notaryIdentities)
|
||||||
)
|
)
|
||||||
driver(extraCordappPackagesToScan = listOf("net.corda.finance"), dsl = {
|
driver(extraCordappPackagesToScan = listOf("net.corda.finance"), isDebug = true) {
|
||||||
val bocManager = User("bocManager", "password1", permissions = setOf(
|
val bocManager = User("bocManager", "password1", permissions = setOf(
|
||||||
startFlow<CashIssueAndPaymentFlow>()) + commonPermissions)
|
startFlow<CashIssueAndPaymentFlow>()) + commonPermissions)
|
||||||
val bigCorpCFO = User("bigCorpCFO", "password2", permissions = emptySet<String>() + commonPermissions)
|
val bigCorpCFO = User("bigCorpCFO", "password2", permissions = emptySet<String>() + commonPermissions)
|
||||||
val (nodeBankOfCorda, nodeBigCorporation) = listOf(
|
val (nodeBankOfCorda, nodeBigCorporation) = listOf(
|
||||||
startNotaryNode(BOC.name, rpcUsers = listOf(bocManager), validating = false),
|
startNode(providedName = BOC.name, rpcUsers = listOf(bocManager)),
|
||||||
startNode(providedName = BIGCORP_LEGAL_NAME, rpcUsers = listOf(bigCorpCFO))
|
startNode(providedName = BIGCORP_LEGAL_NAME, rpcUsers = listOf(bigCorpCFO))
|
||||||
).map { it.getOrThrow() }
|
).map { it.getOrThrow() }
|
||||||
|
|
||||||
@ -51,12 +51,11 @@ class BankOfCordaRPCClientTest {
|
|||||||
|
|
||||||
// Kick-off actual Issuer Flow
|
// Kick-off actual Issuer Flow
|
||||||
val anonymous = true
|
val anonymous = true
|
||||||
val notary = bocProxy.notaryIdentities().first()
|
|
||||||
bocProxy.startFlow(::CashIssueAndPaymentFlow,
|
bocProxy.startFlow(::CashIssueAndPaymentFlow,
|
||||||
1000.DOLLARS, BIG_CORP_PARTY_REF,
|
1000.DOLLARS, BIG_CORP_PARTY_REF,
|
||||||
bigCorporation,
|
bigCorporation,
|
||||||
anonymous,
|
anonymous,
|
||||||
notary).returnValue.getOrThrow()
|
defaultNotaryIdentity).returnValue.getOrThrow()
|
||||||
|
|
||||||
// Check Bank of Corda Vault Updates
|
// Check Bank of Corda Vault Updates
|
||||||
vaultUpdatesBoc.expectEvents {
|
vaultUpdatesBoc.expectEvents {
|
||||||
@ -84,6 +83,6 @@ class BankOfCordaRPCClientTest {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, isDebug = true)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,7 +10,6 @@ import net.corda.finance.flows.CashExitFlow
|
|||||||
import net.corda.finance.flows.CashIssueAndPaymentFlow
|
import net.corda.finance.flows.CashIssueAndPaymentFlow
|
||||||
import net.corda.finance.flows.CashPaymentFlow
|
import net.corda.finance.flows.CashPaymentFlow
|
||||||
import net.corda.node.services.Permissions.Companion.startFlow
|
import net.corda.node.services.Permissions.Companion.startFlow
|
||||||
import net.corda.node.services.transactions.ValidatingNotaryService
|
|
||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.BOC
|
import net.corda.testing.BOC
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
import net.corda.testing.DUMMY_NOTARY
|
||||||
@ -58,7 +57,6 @@ private class BankOfCordaDriver {
|
|||||||
when (role) {
|
when (role) {
|
||||||
Role.ISSUER -> {
|
Role.ISSUER -> {
|
||||||
driver(isDebug = true, extraCordappPackagesToScan = listOf("net.corda.finance.contracts.asset")) {
|
driver(isDebug = true, extraCordappPackagesToScan = listOf("net.corda.finance.contracts.asset")) {
|
||||||
startNotaryNode(providedName = DUMMY_NOTARY.name, validating = true)
|
|
||||||
val bankUser = User(
|
val bankUser = User(
|
||||||
BANK_USERNAME,
|
BANK_USERNAME,
|
||||||
"test",
|
"test",
|
||||||
@ -83,7 +81,7 @@ private class BankOfCordaDriver {
|
|||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val requestParams = IssueRequestParams(options.valueOf(quantity), options.valueOf(currency), BIGCORP_LEGAL_NAME,
|
val requestParams = IssueRequestParams(options.valueOf(quantity), options.valueOf(currency), BIGCORP_LEGAL_NAME,
|
||||||
"1", BOC.name, DUMMY_NOTARY.name.copy(commonName = ValidatingNotaryService.id))
|
"1", BOC.name, DUMMY_NOTARY.name)
|
||||||
when(role) {
|
when(role) {
|
||||||
Role.ISSUE_CASH_RPC -> {
|
Role.ISSUE_CASH_RPC -> {
|
||||||
println("Requesting Cash via RPC ...")
|
println("Requesting Cash via RPC ...")
|
||||||
|
@ -3,7 +3,6 @@ package net.corda.irs
|
|||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.testing.DUMMY_BANK_A
|
import net.corda.testing.DUMMY_BANK_A
|
||||||
import net.corda.testing.DUMMY_BANK_B
|
import net.corda.testing.DUMMY_BANK_B
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,17 +10,17 @@ import net.corda.testing.driver.driver
|
|||||||
* Do not use in a production environment.
|
* Do not use in a production environment.
|
||||||
*/
|
*/
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
driver(dsl = {
|
driver(useTestClock = true, isDebug = true) {
|
||||||
val (controller, nodeA, nodeB) = listOf(
|
val (nodeA, nodeB) = listOf(
|
||||||
startNotaryNode(DUMMY_NOTARY.name, validating = false),
|
|
||||||
startNode(providedName = DUMMY_BANK_A.name),
|
startNode(providedName = DUMMY_BANK_A.name),
|
||||||
startNode(providedName = DUMMY_BANK_B.name))
|
startNode(providedName = DUMMY_BANK_B.name)
|
||||||
.map { it.getOrThrow() }
|
).map { it.getOrThrow() }
|
||||||
|
val controller = defaultNotaryNode.getOrThrow()
|
||||||
|
|
||||||
startWebserver(controller)
|
startWebserver(controller)
|
||||||
startWebserver(nodeA)
|
startWebserver(nodeA)
|
||||||
startWebserver(nodeB)
|
startWebserver(nodeB)
|
||||||
|
|
||||||
waitForAllNodesToFinish()
|
waitForAllNodesToFinish()
|
||||||
}, useTestClock = true, isDebug = true)
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.JsonDeserializer
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
|
import net.corda.client.jackson.JacksonSupport
|
||||||
import net.corda.client.rpc.CordaRPCClient
|
import net.corda.client.rpc.CordaRPCClient
|
||||||
import net.corda.core.contracts.UniqueIdentifier
|
import net.corda.core.contracts.UniqueIdentifier
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
@ -24,6 +25,7 @@ import net.corda.nodeapi.User
|
|||||||
import net.corda.test.spring.springDriver
|
import net.corda.test.spring.springDriver
|
||||||
import net.corda.testing.*
|
import net.corda.testing.*
|
||||||
import net.corda.testing.http.HttpApi
|
import net.corda.testing.http.HttpApi
|
||||||
|
import net.corda.testing.node.NotarySpec
|
||||||
import org.apache.commons.io.IOUtils
|
import org.apache.commons.io.IOUtils
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -44,11 +46,17 @@ class IRSDemoTest : IntegrationTestCategory {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `runs IRS demo`() {
|
fun `runs IRS demo`() {
|
||||||
springDriver(useTestClock = true, isDebug = true, extraCordappPackagesToScan = listOf("net.corda.irs")) {
|
springDriver(
|
||||||
val (controller, nodeA, nodeB) = listOf(
|
useTestClock = true,
|
||||||
startNotaryNode(DUMMY_NOTARY.name, validating = true, rpcUsers = rpcUsers),
|
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name, rpcUsers = rpcUsers)),
|
||||||
|
isDebug = true,
|
||||||
|
extraCordappPackagesToScan = listOf("net.corda.irs")
|
||||||
|
) {
|
||||||
|
val (nodeA, nodeB) = listOf(
|
||||||
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = rpcUsers),
|
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = rpcUsers),
|
||||||
startNode(providedName = DUMMY_BANK_B.name, rpcUsers = rpcUsers)).map { it.getOrThrow() }
|
startNode(providedName = DUMMY_BANK_B.name, rpcUsers = rpcUsers)
|
||||||
|
).map { it.getOrThrow() }
|
||||||
|
val controller = defaultNotaryNode.getOrThrow()
|
||||||
|
|
||||||
log.info("All nodes started")
|
log.info("All nodes started")
|
||||||
|
|
||||||
@ -61,7 +69,7 @@ class IRSDemoTest : IntegrationTestCategory {
|
|||||||
log.info("All webservers started")
|
log.info("All webservers started")
|
||||||
|
|
||||||
val (controllerApi, nodeAApi, nodeBApi) = listOf(controller, nodeA, nodeB).zip(listOf(controllerAddr, nodeAAddr, nodeBAddr)).map {
|
val (controllerApi, nodeAApi, nodeBApi) = listOf(controller, nodeA, nodeB).zip(listOf(controllerAddr, nodeAAddr, nodeBAddr)).map {
|
||||||
val mapper = net.corda.client.jackson.JacksonSupport.createDefaultMapper(it.first.rpc)
|
val mapper = JacksonSupport.createDefaultMapper(it.first.rpc)
|
||||||
registerFinanceJSONMappers(mapper)
|
registerFinanceJSONMappers(mapper)
|
||||||
registerIRSModule(mapper)
|
registerIRSModule(mapper)
|
||||||
HttpApi.fromHostAndPort(it.second, "api/irs", mapper = mapper)
|
HttpApi.fromHostAndPort(it.second, "api/irs", mapper = mapper)
|
||||||
@ -86,7 +94,9 @@ class IRSDemoTest : IntegrationTestCategory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFloatingLegFixCount(nodeApi: HttpApi) = getTrades(nodeApi)[0].calculation.floatingLegPaymentSchedule.count { it.value.rate.ratioUnit != null }
|
private fun getFloatingLegFixCount(nodeApi: HttpApi): Int {
|
||||||
|
return getTrades(nodeApi)[0].calculation.floatingLegPaymentSchedule.count { it.value.rate.ratioUnit != null }
|
||||||
|
}
|
||||||
|
|
||||||
private fun getFixingDateObservable(config: NodeConfiguration): Observable<LocalDate?> {
|
private fun getFixingDateObservable(config: NodeConfiguration): Observable<LocalDate?> {
|
||||||
val client = CordaRPCClient(config.rpcAddress!!)
|
val client = CordaRPCClient(config.rpcAddress!!)
|
||||||
|
@ -6,6 +6,7 @@ import net.corda.core.internal.concurrent.fork
|
|||||||
import net.corda.core.internal.concurrent.map
|
import net.corda.core.internal.concurrent.map
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.testing.driver.*
|
import net.corda.testing.driver.*
|
||||||
|
import net.corda.testing.node.NotarySpec
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import java.net.ConnectException
|
import java.net.ConnectException
|
||||||
@ -41,6 +42,7 @@ fun <A> springDriver(
|
|||||||
useTestClock: Boolean = defaultParameters.useTestClock,
|
useTestClock: Boolean = defaultParameters.useTestClock,
|
||||||
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
|
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
|
||||||
startNodesInProcess: Boolean = defaultParameters.startNodesInProcess,
|
startNodesInProcess: Boolean = defaultParameters.startNodesInProcess,
|
||||||
|
notarySpecs: List<NotarySpec>,
|
||||||
extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan,
|
extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan,
|
||||||
dsl: SpringDriverExposedDSLInterface.() -> A
|
dsl: SpringDriverExposedDSLInterface.() -> A
|
||||||
) = genericDriver(
|
) = genericDriver(
|
||||||
@ -54,9 +56,9 @@ fun <A> springDriver(
|
|||||||
initialiseSerialization = initialiseSerialization,
|
initialiseSerialization = initialiseSerialization,
|
||||||
startNodesInProcess = startNodesInProcess,
|
startNodesInProcess = startNodesInProcess,
|
||||||
extraCordappPackagesToScan = extraCordappPackagesToScan,
|
extraCordappPackagesToScan = extraCordappPackagesToScan,
|
||||||
|
notarySpecs = notarySpecs,
|
||||||
driverDslWrapper = { driverDSL:DriverDSL -> SpringBootDriverDSL(driverDSL) },
|
driverDslWrapper = { driverDSL:DriverDSL -> SpringBootDriverDSL(driverDSL) },
|
||||||
coerce = { it },
|
coerce = { it }, dsl = dsl
|
||||||
dsl = dsl
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class SpringBootDriverDSL(
|
data class SpringBootDriverDSL(
|
||||||
|
@ -31,7 +31,6 @@ import java.util.*
|
|||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.CompletableFuture.allOf
|
import java.util.concurrent.CompletableFuture.allOf
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simulation in which banks execute interest rate swaps with each other, including the fixing events.
|
* A simulation in which banks execute interest rate swaps with each other, including the fixing events.
|
||||||
*/
|
*/
|
||||||
@ -140,8 +139,6 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
|
|||||||
node1.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
|
node1.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
|
||||||
node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
|
node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
|
||||||
|
|
||||||
val notaryId = notary.info.legalIdentities[0]
|
|
||||||
|
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
class StartDealFlow(val otherParty: Party,
|
class StartDealFlow(val otherParty: Party,
|
||||||
val payload: AutoOffer) : FlowLogic<SignedTransaction>() {
|
val payload: AutoOffer) : FlowLogic<SignedTransaction>() {
|
||||||
@ -166,7 +163,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
|
|||||||
|
|
||||||
val instigator = StartDealFlow(
|
val instigator = StartDealFlow(
|
||||||
node2.info.chooseIdentity(),
|
node2.info.chooseIdentity(),
|
||||||
AutoOffer(notaryId, irs)) // TODO Pass notary as parameter to Simulation.
|
AutoOffer(mockNet.defaultNotaryIdentity, irs)) // TODO Pass notary as parameter to Simulation.
|
||||||
val instigatorTxFuture = node1.services.startFlow(instigator).resultFuture
|
val instigatorTxFuture = node1.services.startFlow(instigator).resultFuture
|
||||||
|
|
||||||
return allOf(instigatorTxFuture.toCompletableFuture(), acceptorTxFuture).thenCompose { instigatorTxFuture.toCompletableFuture() }
|
return allOf(instigatorTxFuture.toCompletableFuture(), acceptorTxFuture).thenCompose { instigatorTxFuture.toCompletableFuture() }
|
||||||
|
@ -9,7 +9,6 @@ import net.corda.finance.utils.CityDatabase
|
|||||||
import net.corda.irs.api.NodeInterestRates
|
import net.corda.irs.api.NodeInterestRates
|
||||||
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.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.DUMMY_REGULATOR
|
import net.corda.testing.DUMMY_REGULATOR
|
||||||
import net.corda.testing.node.*
|
import net.corda.testing.node.*
|
||||||
import net.corda.testing.node.MockNetwork.MockNode
|
import net.corda.testing.node.MockNetwork.MockNode
|
||||||
@ -71,14 +70,13 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
|
|||||||
networkSendManuallyPumped = networkSendManuallyPumped,
|
networkSendManuallyPumped = networkSendManuallyPumped,
|
||||||
threadPerNode = runAsync,
|
threadPerNode = runAsync,
|
||||||
cordappPackages = listOf("net.corda.irs.contract", "net.corda.finance.contract", "net.corda.irs"))
|
cordappPackages = listOf("net.corda.irs.contract", "net.corda.finance.contract", "net.corda.irs"))
|
||||||
val notary = mockNet.createNotaryNode(defaultParams.copy(legalName = DUMMY_NOTARY.name), false)
|
|
||||||
// TODO: Regulatory nodes don't actually exist properly, this is a last minute demo request.
|
// TODO: Regulatory nodes don't actually exist properly, this is a last minute demo request.
|
||||||
// So we just fire a message at a node that doesn't know how to handle it, and it'll ignore it.
|
// So we just fire a message at a node that doesn't know how to handle it, and it'll ignore it.
|
||||||
// But that's fine for visualisation purposes.
|
// But that's fine for visualisation purposes.
|
||||||
val regulators = listOf(mockNet.createUnstartedNode(defaultParams.copy(legalName = DUMMY_REGULATOR.name)))
|
val regulators = listOf(mockNet.createUnstartedNode(defaultParams.copy(legalName = DUMMY_REGULATOR.name)))
|
||||||
val ratesOracle = mockNet.createUnstartedNode(defaultParams.copy(legalName = RatesOracleNode.RATES_SERVICE_NAME), ::RatesOracleNode)
|
val ratesOracle = mockNet.createUnstartedNode(defaultParams.copy(legalName = RatesOracleNode.RATES_SERVICE_NAME), ::RatesOracleNode)
|
||||||
// All nodes must be in one of these two lists for the purposes of the visualiser tool.
|
// All nodes must be in one of these two lists for the purposes of the visualiser tool.
|
||||||
val serviceProviders: List<MockNode> = listOf(notary.internals, ratesOracle)
|
val serviceProviders: List<MockNode> = listOf(mockNet.defaultNotaryNode.internals, ratesOracle)
|
||||||
val banks: List<MockNode> = bankLocations.mapIndexed { i, (city, country) ->
|
val banks: List<MockNode> = bankLocations.mapIndexed { i, (city, country) ->
|
||||||
val legalName = CordaX500Name(organisation = "Bank ${'A' + i}", locality = city, country = country)
|
val legalName = CordaX500Name(organisation = "Bank ${'A' + i}", locality = city, country = country)
|
||||||
// Use deterministic seeds so the simulation is stable. Needed so that party owning keys are stable.
|
// Use deterministic seeds so the simulation is stable. Needed so that party owning keys are stable.
|
||||||
|
@ -3,7 +3,9 @@ package net.corda.vega
|
|||||||
import com.opengamma.strata.product.common.BuySell
|
import com.opengamma.strata.product.common.BuySell
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.testing.*
|
import net.corda.testing.DUMMY_BANK_A
|
||||||
|
import net.corda.testing.DUMMY_BANK_B
|
||||||
|
import net.corda.testing.IntegrationTestCategory
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import net.corda.testing.http.HttpApi
|
import net.corda.testing.http.HttpApi
|
||||||
import net.corda.vega.api.PortfolioApi
|
import net.corda.vega.api.PortfolioApi
|
||||||
@ -27,7 +29,6 @@ class SimmValuationTest : IntegrationTestCategory {
|
|||||||
@Test
|
@Test
|
||||||
fun `runs SIMM valuation demo`() {
|
fun `runs SIMM valuation demo`() {
|
||||||
driver(isDebug = true, extraCordappPackagesToScan = listOf("net.corda.vega.contracts")) {
|
driver(isDebug = true, extraCordappPackagesToScan = listOf("net.corda.vega.contracts")) {
|
||||||
startNotaryNode(DUMMY_NOTARY.name, validating = false).getOrThrow()
|
|
||||||
val nodeAFuture = startNode(providedName = nodeALegalName)
|
val nodeAFuture = startNode(providedName = nodeALegalName)
|
||||||
val nodeBFuture = startNode(providedName = nodeBLegalName)
|
val nodeBFuture = startNode(providedName = nodeBLegalName)
|
||||||
val (nodeA, nodeB) = listOf(nodeAFuture, nodeBFuture).map { it.getOrThrow() }
|
val (nodeA, nodeB) = listOf(nodeAFuture, nodeBFuture).map { it.getOrThrow() }
|
||||||
|
@ -4,7 +4,6 @@ import net.corda.core.utilities.getOrThrow
|
|||||||
import net.corda.testing.DUMMY_BANK_A
|
import net.corda.testing.DUMMY_BANK_A
|
||||||
import net.corda.testing.DUMMY_BANK_B
|
import net.corda.testing.DUMMY_BANK_B
|
||||||
import net.corda.testing.DUMMY_BANK_C
|
import net.corda.testing.DUMMY_BANK_C
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,17 +12,17 @@ import net.corda.testing.driver.driver
|
|||||||
* via the web api.
|
* via the web api.
|
||||||
*/
|
*/
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
driver(dsl = {
|
driver(isDebug = true) {
|
||||||
val notaryFuture = startNotaryNode(DUMMY_NOTARY.name, validating = false)
|
val (nodeA, nodeB, nodeC) = listOf(
|
||||||
val nodeAFuture = startNode(providedName = DUMMY_BANK_A.name)
|
startNode(providedName = DUMMY_BANK_A.name),
|
||||||
val nodeBFuture = startNode(providedName = DUMMY_BANK_B.name)
|
startNode(providedName = DUMMY_BANK_B.name),
|
||||||
val nodeCFuture = startNode(providedName = DUMMY_BANK_C.name)
|
startNode(providedName = DUMMY_BANK_C.name)
|
||||||
val (nodeA, nodeB, nodeC) = listOf(nodeAFuture, nodeBFuture, nodeCFuture, notaryFuture).map { it.getOrThrow() }
|
).map { it.getOrThrow() }
|
||||||
|
|
||||||
startWebserver(nodeA)
|
startWebserver(nodeA)
|
||||||
startWebserver(nodeB)
|
startWebserver(nodeB)
|
||||||
startWebserver(nodeC)
|
startWebserver(nodeC)
|
||||||
|
|
||||||
waitForAllNodesToFinish()
|
waitForAllNodesToFinish()
|
||||||
}, isDebug = true)
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,10 @@ import net.corda.finance.flows.CashPaymentFlow
|
|||||||
import net.corda.node.services.Permissions.Companion.all
|
import net.corda.node.services.Permissions.Companion.all
|
||||||
import net.corda.node.services.Permissions.Companion.startFlow
|
import net.corda.node.services.Permissions.Companion.startFlow
|
||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.*
|
import net.corda.testing.BOC
|
||||||
|
import net.corda.testing.DUMMY_BANK_A
|
||||||
|
import net.corda.testing.DUMMY_BANK_B
|
||||||
|
import net.corda.testing.chooseIdentity
|
||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import net.corda.testing.driver.poll
|
import net.corda.testing.driver.poll
|
||||||
@ -30,8 +33,7 @@ class TraderDemoTest {
|
|||||||
startFlow<CommercialPaperIssueFlow>(),
|
startFlow<CommercialPaperIssueFlow>(),
|
||||||
all()))
|
all()))
|
||||||
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance")) {
|
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance")) {
|
||||||
val (_, nodeA, nodeB, bankNode) = listOf(
|
val (nodeA, nodeB, bankNode) = listOf(
|
||||||
startNotaryNode(DUMMY_NOTARY.name, validating = false),
|
|
||||||
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = listOf(demoUser)),
|
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = listOf(demoUser)),
|
||||||
startNode(providedName = DUMMY_BANK_B.name, rpcUsers = listOf(demoUser)),
|
startNode(providedName = DUMMY_BANK_B.name, rpcUsers = listOf(demoUser)),
|
||||||
startNode(providedName = BOC.name, rpcUsers = listOf(bankUser))
|
startNode(providedName = BOC.name, rpcUsers = listOf(bankUser))
|
||||||
|
@ -8,7 +8,6 @@ import net.corda.nodeapi.User
|
|||||||
import net.corda.testing.BOC
|
import net.corda.testing.BOC
|
||||||
import net.corda.testing.DUMMY_BANK_A
|
import net.corda.testing.DUMMY_BANK_A
|
||||||
import net.corda.testing.DUMMY_BANK_B
|
import net.corda.testing.DUMMY_BANK_B
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import net.corda.traderdemo.flow.CommercialPaperIssueFlow
|
import net.corda.traderdemo.flow.CommercialPaperIssueFlow
|
||||||
import net.corda.traderdemo.flow.SellerFlow
|
import net.corda.traderdemo.flow.SellerFlow
|
||||||
@ -27,7 +26,6 @@ fun main(args: Array<String>) {
|
|||||||
val user = User("user1", "test", permissions = setOf(startFlow<CashIssueFlow>(),
|
val user = User("user1", "test", permissions = setOf(startFlow<CashIssueFlow>(),
|
||||||
startFlow<CommercialPaperIssueFlow>(),
|
startFlow<CommercialPaperIssueFlow>(),
|
||||||
startFlow<SellerFlow>()))
|
startFlow<SellerFlow>()))
|
||||||
startNotaryNode(DUMMY_NOTARY.name, validating = false)
|
|
||||||
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = demoUser)
|
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = demoUser)
|
||||||
startNode(providedName = DUMMY_BANK_B.name, rpcUsers = demoUser)
|
startNode(providedName = DUMMY_BANK_B.name, rpcUsers = demoUser)
|
||||||
startNode(providedName = BOC.name, rpcUsers = listOf(user))
|
startNode(providedName = BOC.name, rpcUsers = listOf(user))
|
||||||
|
@ -290,7 +290,6 @@ class FlowStackSnapshotTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `flowStackSnapshot object is serializable`() {
|
fun `flowStackSnapshot object is serializable`() {
|
||||||
val mockNet = MockNetwork(threadPerNode = true)
|
val mockNet = MockNetwork(threadPerNode = true)
|
||||||
mockNet.createNotaryNode()
|
|
||||||
val node = mockNet.createPartyNode()
|
val node = mockNet.createPartyNode()
|
||||||
node.internals.registerInitiatedFlow(DummyFlow::class.java)
|
node.internals.registerInitiatedFlow(DummyFlow::class.java)
|
||||||
node.services.startFlow(FlowStackSnapshotSerializationTestingFlow()).resultFuture.get()
|
node.services.startFlow(FlowStackSnapshotSerializationTestingFlow()).resultFuture.get()
|
||||||
|
@ -7,7 +7,6 @@ import net.corda.core.internal.readLines
|
|||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.node.internal.NodeStartup
|
import net.corda.node.internal.NodeStartup
|
||||||
import net.corda.testing.DUMMY_BANK_A
|
import net.corda.testing.DUMMY_BANK_A
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.DUMMY_REGULATOR
|
import net.corda.testing.DUMMY_REGULATOR
|
||||||
import net.corda.testing.ProjectStructure.projectRootDir
|
import net.corda.testing.ProjectStructure.projectRootDir
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
@ -18,7 +17,6 @@ import java.util.concurrent.ScheduledExecutorService
|
|||||||
class DriverTests {
|
class DriverTests {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private val executorService: ScheduledExecutorService = Executors.newScheduledThreadPool(2)
|
private val executorService: ScheduledExecutorService = Executors.newScheduledThreadPool(2)
|
||||||
|
|
||||||
private fun nodeMustBeUp(handleFuture: CordaFuture<out NodeHandle>) = handleFuture.getOrThrow().apply {
|
private fun nodeMustBeUp(handleFuture: CordaFuture<out NodeHandle>) = handleFuture.getOrThrow().apply {
|
||||||
@ -32,26 +30,15 @@ class DriverTests {
|
|||||||
// Check that the port is bound
|
// Check that the port is bound
|
||||||
addressMustNotBeBound(executorService, hostAndPort)
|
addressMustNotBeBound(executorService, hostAndPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `simple node startup and shutdown`() {
|
fun `simple node startup and shutdown`() {
|
||||||
val handles = driver {
|
val handle = driver {
|
||||||
val notary = startNotaryNode(DUMMY_NOTARY.name, validating = false)
|
|
||||||
val regulator = startNode(providedName = DUMMY_REGULATOR.name)
|
val regulator = startNode(providedName = DUMMY_REGULATOR.name)
|
||||||
listOf(nodeMustBeUp(notary), nodeMustBeUp(regulator))
|
nodeMustBeUp(regulator)
|
||||||
}
|
}
|
||||||
handles.map { nodeMustBeDown(it) }
|
nodeMustBeDown(handle)
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `starting node with no services`() {
|
|
||||||
val noService = driver {
|
|
||||||
val noService = startNode(providedName = DUMMY_BANK_A.name)
|
|
||||||
nodeMustBeUp(noService)
|
|
||||||
}
|
|
||||||
nodeMustBeDown(noService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -15,17 +15,11 @@ import net.corda.testing.driver.DriverDSLExposedInterface
|
|||||||
/**
|
/**
|
||||||
* A simple wrapper for objects provided by the integration test driver DSL. The fields are lazy so
|
* A simple wrapper for objects provided by the integration test driver DSL. The fields are lazy so
|
||||||
* node construction won't start until you access the members. You can get one of these from the
|
* node construction won't start until you access the members. You can get one of these from the
|
||||||
* [alice], [bob] and [notaryAliceAndBob] functions.
|
* [alice], [bob] and [aliceAndBob] functions.
|
||||||
*/
|
*/
|
||||||
class PredefinedTestNode internal constructor(party: Party, driver: DriverDSLExposedInterface, ifNotaryIsValidating: Boolean?) {
|
class PredefinedTestNode internal constructor(party: Party, driver: DriverDSLExposedInterface) {
|
||||||
val rpcUsers = listOf(User("admin", "admin", setOf("ALL"))) // TODO: Randomize?
|
val rpcUsers = listOf(User("admin", "admin", setOf("ALL"))) // TODO: Randomize?
|
||||||
val nodeFuture by lazy {
|
val nodeFuture by lazy { driver.startNode(providedName = party.name, rpcUsers = rpcUsers) }
|
||||||
if (ifNotaryIsValidating != null) {
|
|
||||||
driver.startNotaryNode(providedName = party.name, rpcUsers = rpcUsers, validating = ifNotaryIsValidating)
|
|
||||||
} else {
|
|
||||||
driver.startNode(providedName = party.name, rpcUsers = rpcUsers)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val node by lazy { nodeFuture.get()!! }
|
val node by lazy { nodeFuture.get()!! }
|
||||||
val rpc by lazy { node.rpcClientToNode() }
|
val rpc by lazy { node.rpcClientToNode() }
|
||||||
|
|
||||||
@ -38,28 +32,21 @@ class PredefinedTestNode internal constructor(party: Party, driver: DriverDSLExp
|
|||||||
* Returns a plain, entirely stock node pre-configured with the [ALICE] identity. Note that a random key will be generated
|
* Returns a plain, entirely stock node pre-configured with the [ALICE] identity. Note that a random key will be generated
|
||||||
* for it: you won't have [ALICE_KEY].
|
* for it: you won't have [ALICE_KEY].
|
||||||
*/
|
*/
|
||||||
fun DriverDSLExposedInterface.alice(): PredefinedTestNode = PredefinedTestNode(ALICE, this, null)
|
fun DriverDSLExposedInterface.alice(): PredefinedTestNode = PredefinedTestNode(ALICE, this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a plain, entirely stock node pre-configured with the [BOB] identity. Note that a random key will be generated
|
* Returns a plain, entirely stock node pre-configured with the [BOB] identity. Note that a random key will be generated
|
||||||
* for it: you won't have [BOB_KEY].
|
* for it: you won't have [BOB_KEY].
|
||||||
*/
|
*/
|
||||||
fun DriverDSLExposedInterface.bob(): PredefinedTestNode = PredefinedTestNode(BOB, this, null)
|
fun DriverDSLExposedInterface.bob(): PredefinedTestNode = PredefinedTestNode(BOB, this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a plain single node notary pre-configured with the [DUMMY_NOTARY] identity. Note that a random key will be generated
|
* Returns plain, entirely stock nodes pre-configured with the [ALICE] and [BOB] X.500 names in that order. They have been
|
||||||
* for it: you won't have [DUMMY_NOTARY_KEY].
|
* started up in parallel and are now ready to use.
|
||||||
*/
|
*/
|
||||||
fun DriverDSLExposedInterface.notary(): PredefinedTestNode = PredefinedTestNode(DUMMY_NOTARY, this, true)
|
fun DriverDSLExposedInterface.aliceAndBob(): List<PredefinedTestNode> {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns plain, entirely stock nodes pre-configured with the [ALICE], [BOB] and [DUMMY_NOTARY] X.500 names in that
|
|
||||||
* order. They have been started up in parallel and are now ready to use.
|
|
||||||
*/
|
|
||||||
fun DriverDSLExposedInterface.notaryAliceAndBob(): List<PredefinedTestNode> {
|
|
||||||
val notary = notary()
|
|
||||||
val alice = alice()
|
val alice = alice()
|
||||||
val bob = bob()
|
val bob = bob()
|
||||||
listOf(notary.nodeFuture, alice.nodeFuture, bob.nodeFuture).transpose().get()
|
listOf(alice.nodeFuture, bob.nodeFuture).transpose().get()
|
||||||
return listOf(alice, bob, notary)
|
return listOf(alice, bob)
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import net.corda.nodeapi.RPCApi
|
|||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.nodeapi.internal.serialization.KRYO_RPC_CLIENT_CONTEXT
|
import net.corda.nodeapi.internal.serialization.KRYO_RPC_CLIENT_CONTEXT
|
||||||
import net.corda.testing.driver.*
|
import net.corda.testing.driver.*
|
||||||
|
import net.corda.testing.node.NotarySpec
|
||||||
import org.apache.activemq.artemis.api.core.SimpleString
|
import org.apache.activemq.artemis.api.core.SimpleString
|
||||||
import org.apache.activemq.artemis.api.core.TransportConfiguration
|
import org.apache.activemq.artemis.api.core.TransportConfiguration
|
||||||
import org.apache.activemq.artemis.api.core.client.ActiveMQClient
|
import org.apache.activemq.artemis.api.core.client.ActiveMQClient
|
||||||
@ -230,6 +231,7 @@ fun <A> rpcDriver(
|
|||||||
initialiseSerialization: Boolean = true,
|
initialiseSerialization: Boolean = true,
|
||||||
startNodesInProcess: Boolean = false,
|
startNodesInProcess: Boolean = false,
|
||||||
extraCordappPackagesToScan: List<String> = emptyList(),
|
extraCordappPackagesToScan: List<String> = emptyList(),
|
||||||
|
notarySpecs: List<NotarySpec> = emptyList(),
|
||||||
dsl: RPCDriverExposedDSLInterface.() -> A
|
dsl: RPCDriverExposedDSLInterface.() -> A
|
||||||
) = genericDriver(
|
) = genericDriver(
|
||||||
driverDsl = RPCDriverDSL(
|
driverDsl = RPCDriverDSL(
|
||||||
@ -241,7 +243,8 @@ fun <A> rpcDriver(
|
|||||||
useTestClock = useTestClock,
|
useTestClock = useTestClock,
|
||||||
isDebug = isDebug,
|
isDebug = isDebug,
|
||||||
startNodesInProcess = startNodesInProcess,
|
startNodesInProcess = startNodesInProcess,
|
||||||
extraCordappPackagesToScan = extraCordappPackagesToScan
|
extraCordappPackagesToScan = extraCordappPackagesToScan,
|
||||||
|
notarySpecs = notarySpecs
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
coerce = { it },
|
coerce = { it },
|
||||||
|
@ -16,6 +16,7 @@ import net.corda.core.identity.Party
|
|||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.*
|
||||||
import net.corda.core.internal.concurrent.*
|
import net.corda.core.internal.concurrent.*
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.node.NotaryInfo
|
import net.corda.core.node.NotaryInfo
|
||||||
import net.corda.core.node.services.NetworkMapCache
|
import net.corda.core.node.services.NetworkMapCache
|
||||||
@ -33,13 +34,12 @@ import net.corda.nodeapi.NodeInfoFilesCopier
|
|||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.nodeapi.config.toConfig
|
import net.corda.nodeapi.config.toConfig
|
||||||
import net.corda.nodeapi.internal.addShutdownHook
|
import net.corda.nodeapi.internal.addShutdownHook
|
||||||
import net.corda.testing.ALICE
|
import net.corda.testing.*
|
||||||
import net.corda.testing.BOB
|
|
||||||
import net.corda.testing.DUMMY_BANK_A
|
|
||||||
import net.corda.testing.common.internal.NetworkParametersCopier
|
import net.corda.testing.common.internal.NetworkParametersCopier
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.initialiseTestSerialization
|
import net.corda.testing.node.ClusterSpec
|
||||||
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
|
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
|
||||||
|
import net.corda.testing.node.NotarySpec
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
@ -84,10 +84,48 @@ private val DRIVER_REQUIRED_PERMISSIONS = setOf(
|
|||||||
invokeRpc(CordaRPCOps::networkMapSnapshot)
|
invokeRpc(CordaRPCOps::networkMapSnapshot)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object ecapsulating a notary started automatically by the driver.
|
||||||
|
*/
|
||||||
|
data class NotaryHandle(val identity: Party, val validating: Boolean, val nodeHandles: CordaFuture<List<NodeHandle>>)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the interface that's exposed to DSL users.
|
* This is the interface that's exposed to DSL users.
|
||||||
*/
|
*/
|
||||||
interface DriverDSLExposedInterface : CordformContext {
|
interface DriverDSLExposedInterface : CordformContext {
|
||||||
|
/** Returns a list of [NotaryHandle]s matching the list of [NotarySpec]s passed into [driver]. */
|
||||||
|
val notaryHandles: List<NotaryHandle>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the [NotaryHandle] for the single notary on the network. Throws if there are none or more than one.
|
||||||
|
* @see notaryHandles
|
||||||
|
*/
|
||||||
|
val defaultNotaryHandle: NotaryHandle get() {
|
||||||
|
return when (notaryHandles.size) {
|
||||||
|
0 -> throw IllegalStateException("There are no notaries defined on the network")
|
||||||
|
1 -> notaryHandles[0]
|
||||||
|
else -> throw IllegalStateException("There is more than one notary defined on the network")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the identity of the single notary on the network. Throws if there are none or more than one.
|
||||||
|
* @see defaultNotaryHandle
|
||||||
|
*/
|
||||||
|
val defaultNotaryIdentity: Party get() = defaultNotaryHandle.identity
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a [CordaFuture] on the [NodeHandle] for the single-node notary on the network. Throws if there
|
||||||
|
* are no notaries or more than one, or if the notary is a distributed cluster.
|
||||||
|
* @see defaultNotaryHandle
|
||||||
|
* @see notaryHandles
|
||||||
|
*/
|
||||||
|
val defaultNotaryNode: CordaFuture<NodeHandle> get() {
|
||||||
|
return defaultNotaryHandle.nodeHandles.map {
|
||||||
|
it.singleOrNull() ?: throw IllegalStateException("Default notary is not a single node")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a node.
|
* Start a node.
|
||||||
*
|
*
|
||||||
@ -110,13 +148,6 @@ interface DriverDSLExposedInterface : CordformContext {
|
|||||||
startInSameProcess: Boolean? = defaultParameters.startInSameProcess,
|
startInSameProcess: Boolean? = defaultParameters.startInSameProcess,
|
||||||
maximumHeapSize: String = defaultParameters.maximumHeapSize): CordaFuture<NodeHandle>
|
maximumHeapSize: String = defaultParameters.maximumHeapSize): CordaFuture<NodeHandle>
|
||||||
|
|
||||||
// TODO This method has been added temporarily, to be deleted once the set of notaries is defined at the network level.
|
|
||||||
fun startNotaryNode(providedName: CordaX500Name,
|
|
||||||
rpcUsers: List<User> = emptyList(),
|
|
||||||
verifierType: VerifierType = VerifierType.InMemory,
|
|
||||||
customOverrides: Map<String, Any?> = emptyMap(),
|
|
||||||
validating: Boolean = true): CordaFuture<NodeHandle>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function for starting a [Node] with custom parameters from Java.
|
* Helper function for starting a [Node] with custom parameters from Java.
|
||||||
*
|
*
|
||||||
@ -131,24 +162,6 @@ interface DriverDSLExposedInterface : CordformContext {
|
|||||||
maximumHeapSize: String = "200m"
|
maximumHeapSize: String = "200m"
|
||||||
): List<CordaFuture<NodeHandle>>
|
): List<CordaFuture<NodeHandle>>
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a distributed notary cluster.
|
|
||||||
*
|
|
||||||
* @param notaryName The legal name of the advertised distributed notary service.
|
|
||||||
* @param clusterSize Number of nodes to create for the cluster.
|
|
||||||
* @param verifierType The type of transaction verifier to use. See: [VerifierType]
|
|
||||||
* @param rpcUsers List of users who are authorised to use the RPC system. Defaults to empty list.
|
|
||||||
* @param startInSameProcess Determines if the node should be started inside the same process the Driver is running
|
|
||||||
* in. If null the Driver-level value will be used.
|
|
||||||
* @return The [Party] identity of the distributed notary service, and the [NodeInfo]s of the notaries in the cluster.
|
|
||||||
*/
|
|
||||||
fun startNotaryCluster(
|
|
||||||
notaryName: CordaX500Name,
|
|
||||||
clusterSize: Int = 3,
|
|
||||||
verifierType: VerifierType = VerifierType.InMemory,
|
|
||||||
rpcUsers: List<User> = emptyList(),
|
|
||||||
startInSameProcess: Boolean? = null): CordaFuture<Pair<Party, List<NodeHandle>>>
|
|
||||||
|
|
||||||
/** Call [startWebserver] with a default maximumHeapSize. */
|
/** Call [startWebserver] with a default maximumHeapSize. */
|
||||||
fun startWebserver(handle: NodeHandle): CordaFuture<WebserverHandle> = startWebserver(handle, "200m")
|
fun startWebserver(handle: NodeHandle): CordaFuture<WebserverHandle> = startWebserver(handle, "200m")
|
||||||
|
|
||||||
@ -310,6 +323,8 @@ data class NodeParameters(
|
|||||||
* @param useTestClock If true the test clock will be used in Node.
|
* @param useTestClock If true the test clock will be used in Node.
|
||||||
* @param startNodesInProcess Provides the default behaviour of whether new nodes should start inside this process or
|
* @param startNodesInProcess Provides the default behaviour of whether new nodes should start inside this process or
|
||||||
* not. Note that this may be overridden in [DriverDSLExposedInterface.startNode].
|
* not. Note that this may be overridden in [DriverDSLExposedInterface.startNode].
|
||||||
|
* @param notarySpecs The notaries advertised in the [NetworkParameters] for this network. These nodes will be started
|
||||||
|
* automatically and will be available from [DriverDSLExposedInterface.notaryHandles]. Defaults to a simple validating notary.
|
||||||
* @param dsl The dsl itself.
|
* @param dsl The dsl itself.
|
||||||
* @return The value returned in the [dsl] closure.
|
* @return The value returned in the [dsl] closure.
|
||||||
*/
|
*/
|
||||||
@ -323,6 +338,7 @@ fun <A> driver(
|
|||||||
useTestClock: Boolean = defaultParameters.useTestClock,
|
useTestClock: Boolean = defaultParameters.useTestClock,
|
||||||
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
|
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
|
||||||
startNodesInProcess: Boolean = defaultParameters.startNodesInProcess,
|
startNodesInProcess: Boolean = defaultParameters.startNodesInProcess,
|
||||||
|
notarySpecs: List<NotarySpec> = defaultParameters.notarySpecs,
|
||||||
extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan,
|
extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan,
|
||||||
dsl: DriverDSLExposedInterface.() -> A
|
dsl: DriverDSLExposedInterface.() -> A
|
||||||
): A {
|
): A {
|
||||||
@ -335,6 +351,7 @@ fun <A> driver(
|
|||||||
useTestClock = useTestClock,
|
useTestClock = useTestClock,
|
||||||
isDebug = isDebug,
|
isDebug = isDebug,
|
||||||
startNodesInProcess = startNodesInProcess,
|
startNodesInProcess = startNodesInProcess,
|
||||||
|
notarySpecs = notarySpecs,
|
||||||
extraCordappPackagesToScan = extraCordappPackagesToScan
|
extraCordappPackagesToScan = extraCordappPackagesToScan
|
||||||
),
|
),
|
||||||
coerce = { it },
|
coerce = { it },
|
||||||
@ -368,6 +385,7 @@ data class DriverParameters(
|
|||||||
val useTestClock: Boolean = false,
|
val useTestClock: Boolean = false,
|
||||||
val initialiseSerialization: Boolean = true,
|
val initialiseSerialization: Boolean = true,
|
||||||
val startNodesInProcess: Boolean = false,
|
val startNodesInProcess: Boolean = false,
|
||||||
|
val notarySpecs: List<NotarySpec> = listOf(NotarySpec(DUMMY_NOTARY.name)),
|
||||||
val extraCordappPackagesToScan: List<String> = emptyList()
|
val extraCordappPackagesToScan: List<String> = emptyList()
|
||||||
) {
|
) {
|
||||||
fun setIsDebug(isDebug: Boolean) = copy(isDebug = isDebug)
|
fun setIsDebug(isDebug: Boolean) = copy(isDebug = isDebug)
|
||||||
@ -379,6 +397,7 @@ data class DriverParameters(
|
|||||||
fun setInitialiseSerialization(initialiseSerialization: Boolean) = copy(initialiseSerialization = initialiseSerialization)
|
fun setInitialiseSerialization(initialiseSerialization: Boolean) = copy(initialiseSerialization = initialiseSerialization)
|
||||||
fun setStartNodesInProcess(startNodesInProcess: Boolean) = copy(startNodesInProcess = startNodesInProcess)
|
fun setStartNodesInProcess(startNodesInProcess: Boolean) = copy(startNodesInProcess = startNodesInProcess)
|
||||||
fun setExtraCordappPackagesToScan(extraCordappPackagesToScan: List<String>) = copy(extraCordappPackagesToScan = extraCordappPackagesToScan)
|
fun setExtraCordappPackagesToScan(extraCordappPackagesToScan: List<String>) = copy(extraCordappPackagesToScan = extraCordappPackagesToScan)
|
||||||
|
fun setNotarySpecs(notarySpecs: List<NotarySpec>) = copy(notarySpecs = notarySpecs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -428,10 +447,10 @@ fun <DI : DriverDSLExposedInterface, D : DriverDSLInternalInterface, A> genericD
|
|||||||
useTestClock: Boolean = defaultParameters.useTestClock,
|
useTestClock: Boolean = defaultParameters.useTestClock,
|
||||||
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
|
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
|
||||||
startNodesInProcess: Boolean = defaultParameters.startNodesInProcess,
|
startNodesInProcess: Boolean = defaultParameters.startNodesInProcess,
|
||||||
|
notarySpecs: List<NotarySpec>,
|
||||||
extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan,
|
extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan,
|
||||||
driverDslWrapper: (DriverDSL) -> D,
|
driverDslWrapper: (DriverDSL) -> D,
|
||||||
coerce: (D) -> DI,
|
coerce: (D) -> DI, dsl: DI.() -> A
|
||||||
dsl: DI.() -> A
|
|
||||||
): A {
|
): A {
|
||||||
val serializationEnv = initialiseTestSerialization(initialiseSerialization)
|
val serializationEnv = initialiseTestSerialization(initialiseSerialization)
|
||||||
val driverDsl = driverDslWrapper(
|
val driverDsl = driverDslWrapper(
|
||||||
@ -443,7 +462,8 @@ fun <DI : DriverDSLExposedInterface, D : DriverDSLInternalInterface, A> genericD
|
|||||||
useTestClock = useTestClock,
|
useTestClock = useTestClock,
|
||||||
isDebug = isDebug,
|
isDebug = isDebug,
|
||||||
startNodesInProcess = startNodesInProcess,
|
startNodesInProcess = startNodesInProcess,
|
||||||
extraCordappPackagesToScan = extraCordappPackagesToScan
|
extraCordappPackagesToScan = extraCordappPackagesToScan,
|
||||||
|
notarySpecs = notarySpecs
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val shutdownHook = addShutdownHook(driverDsl::shutdown)
|
val shutdownHook = addShutdownHook(driverDsl::shutdown)
|
||||||
@ -643,7 +663,8 @@ class DriverDSL(
|
|||||||
val useTestClock: Boolean,
|
val useTestClock: Boolean,
|
||||||
val isDebug: Boolean,
|
val isDebug: Boolean,
|
||||||
val startNodesInProcess: Boolean,
|
val startNodesInProcess: Boolean,
|
||||||
extraCordappPackagesToScan: List<String>
|
extraCordappPackagesToScan: List<String>,
|
||||||
|
val notarySpecs: List<NotarySpec>
|
||||||
) : DriverDSLInternalInterface {
|
) : DriverDSLInternalInterface {
|
||||||
private var _executorService: ScheduledExecutorService? = null
|
private var _executorService: ScheduledExecutorService? = null
|
||||||
val executorService get() = _executorService!!
|
val executorService get() = _executorService!!
|
||||||
@ -656,7 +677,9 @@ class DriverDSL(
|
|||||||
private val nodeInfoFilesCopier = NodeInfoFilesCopier()
|
private val nodeInfoFilesCopier = NodeInfoFilesCopier()
|
||||||
// Map from a nodes legal name to an observable emitting the number of nodes in its network map.
|
// Map from a nodes legal name to an observable emitting the number of nodes in its network map.
|
||||||
private val countObservables = mutableMapOf<CordaX500Name, Observable<Int>>()
|
private val countObservables = mutableMapOf<CordaX500Name, Observable<Int>>()
|
||||||
private var networkParameters: NetworkParametersCopier? = null
|
private lateinit var _notaries: List<NotaryHandle>
|
||||||
|
override val notaryHandles: List<NotaryHandle> get() = _notaries
|
||||||
|
private lateinit var networkParameters: NetworkParametersCopier
|
||||||
|
|
||||||
class State {
|
class State {
|
||||||
val processes = ArrayList<CordaFuture<Process>>()
|
val processes = ArrayList<CordaFuture<Process>>()
|
||||||
@ -744,16 +767,6 @@ class DriverDSL(
|
|||||||
return startNodeInternal(config, webAddress, startInSameProcess, maximumHeapSize)
|
return startNodeInternal(config, webAddress, startInSameProcess, maximumHeapSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startNotaryNode(providedName: CordaX500Name,
|
|
||||||
rpcUsers: List<User>,
|
|
||||||
verifierType: VerifierType,
|
|
||||||
customOverrides: Map<String, Any?>,
|
|
||||||
validating: Boolean): CordaFuture<NodeHandle> {
|
|
||||||
createNetworkParameters(listOf(providedName), providedName, validating, "identity")
|
|
||||||
val config = customOverrides + NotaryConfig(validating).toConfigMap()
|
|
||||||
return startNode(providedName = providedName, rpcUsers = rpcUsers, verifierType = verifierType, customOverrides = config)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun startNodes(nodes: List<CordformNode>, startInSameProcess: Boolean?, maximumHeapSize: String): List<CordaFuture<NodeHandle>> {
|
override fun startNodes(nodes: List<CordformNode>, startInSameProcess: Boolean?, maximumHeapSize: String): List<CordaFuture<NodeHandle>> {
|
||||||
return nodes.map { node ->
|
return nodes.map { node ->
|
||||||
portAllocation.nextHostAndPort() // rpcAddress
|
portAllocation.nextHostAndPort() // rpcAddress
|
||||||
@ -772,72 +785,6 @@ class DriverDSL(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO This mapping is done is several plaecs including the gradle plugin. In general we need a better way of
|
|
||||||
// generating the configs for the nodes, probably making use of Any.toConfig()
|
|
||||||
private fun NotaryConfig.toConfigMap(): Map<String, Any> = mapOf("notary" to toConfig().root().unwrapped())
|
|
||||||
|
|
||||||
override fun startNotaryCluster(
|
|
||||||
notaryName: CordaX500Name,
|
|
||||||
clusterSize: Int,
|
|
||||||
verifierType: VerifierType,
|
|
||||||
rpcUsers: List<User>,
|
|
||||||
startInSameProcess: Boolean?
|
|
||||||
): CordaFuture<Pair<Party, List<NodeHandle>>> {
|
|
||||||
fun notaryConfig(nodeAddress: NetworkHostAndPort, clusterAddress: NetworkHostAndPort? = null): Map<String, Any> {
|
|
||||||
val clusterAddresses = if (clusterAddress != null) listOf(clusterAddress) else emptyList()
|
|
||||||
val config = NotaryConfig(validating = true, raft = RaftConfig(nodeAddress = nodeAddress, clusterAddresses = clusterAddresses))
|
|
||||||
return config.toConfigMap()
|
|
||||||
}
|
|
||||||
|
|
||||||
require(clusterSize > 0)
|
|
||||||
|
|
||||||
val nodeNames = (0 until clusterSize).map { notaryName.copy(organisation = "${notaryName.organisation}-$it") }
|
|
||||||
val notaryIdentity = createNetworkParameters(
|
|
||||||
nodeNames,
|
|
||||||
notaryName,
|
|
||||||
validating = true,
|
|
||||||
serviceId = NotaryService.constructId(validating = true, raft = true))
|
|
||||||
|
|
||||||
val clusterAddress = portAllocation.nextHostAndPort()
|
|
||||||
|
|
||||||
// Start the first node that will bootstrap the cluster
|
|
||||||
val firstNotaryFuture = startNode(
|
|
||||||
providedName = nodeNames[0],
|
|
||||||
rpcUsers = rpcUsers,
|
|
||||||
verifierType = verifierType,
|
|
||||||
customOverrides = notaryConfig(clusterAddress) + mapOf(
|
|
||||||
"database.serverNameTablePrefix" to nodeNames[0].toString().replace(Regex("[^0-9A-Za-z]+"), "")
|
|
||||||
),
|
|
||||||
startInSameProcess = startInSameProcess
|
|
||||||
)
|
|
||||||
|
|
||||||
// All other nodes will join the cluster
|
|
||||||
val restNotaryFutures = nodeNames.drop(1).map {
|
|
||||||
val nodeAddress = portAllocation.nextHostAndPort()
|
|
||||||
startNode(
|
|
||||||
providedName = it,
|
|
||||||
rpcUsers = rpcUsers,
|
|
||||||
verifierType = verifierType,
|
|
||||||
customOverrides = notaryConfig(nodeAddress, clusterAddress) + mapOf(
|
|
||||||
"database.serverNameTablePrefix" to it.toString().replace(Regex("[^0-9A-Za-z]+"), "")
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
return firstNotaryFuture.flatMap { firstNotary ->
|
|
||||||
restNotaryFutures.transpose().map { restNotaries -> Pair(notaryIdentity, listOf(firstNotary) + restNotaries) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createNetworkParameters(notaryNodeNames: List<CordaX500Name>, notaryName: CordaX500Name, validating: Boolean, serviceId: String): Party {
|
|
||||||
check(networkParameters == null) { "Notaries must be started first" }
|
|
||||||
val identity = ServiceIdentityGenerator.generateToDisk(
|
|
||||||
notaryNodeNames.map { baseDirectory(it) },
|
|
||||||
notaryName,
|
|
||||||
serviceId)
|
|
||||||
networkParameters = NetworkParametersCopier(testNetworkParameters(listOf(NotaryInfo(identity, validating))))
|
|
||||||
return identity
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun queryWebserver(handle: NodeHandle, process: Process): WebserverHandle {
|
private fun queryWebserver(handle: NodeHandle, process: Process): WebserverHandle {
|
||||||
val protocol = if (handle.configuration.useHTTPS) "https://" else "http://"
|
val protocol = if (handle.configuration.useHTTPS) "https://" else "http://"
|
||||||
val url = URL("$protocol${handle.webAddress}/api/status")
|
val url = URL("$protocol${handle.webAddress}/api/status")
|
||||||
@ -866,6 +813,97 @@ class DriverDSL(
|
|||||||
_executorService = Executors.newScheduledThreadPool(2, ThreadFactoryBuilder().setNameFormat("driver-pool-thread-%d").build())
|
_executorService = Executors.newScheduledThreadPool(2, ThreadFactoryBuilder().setNameFormat("driver-pool-thread-%d").build())
|
||||||
_shutdownManager = ShutdownManager(executorService)
|
_shutdownManager = ShutdownManager(executorService)
|
||||||
shutdownManager.registerShutdown { nodeInfoFilesCopier.close() }
|
shutdownManager.registerShutdown { nodeInfoFilesCopier.close() }
|
||||||
|
val notaryInfos = generateNotaryIdentities()
|
||||||
|
// The network parameters must be serialised before starting any of the nodes
|
||||||
|
networkParameters = NetworkParametersCopier(testNetworkParameters(notaryInfos))
|
||||||
|
val nodeHandles = startNotaries()
|
||||||
|
_notaries = notaryInfos.zip(nodeHandles) { (identity, validating), nodes -> NotaryHandle(identity, validating, nodes) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateNotaryIdentities(): List<NotaryInfo> {
|
||||||
|
return notarySpecs.map { spec ->
|
||||||
|
val identity = if (spec.cluster == null) {
|
||||||
|
ServiceIdentityGenerator.generateToDisk(
|
||||||
|
dirs = listOf(baseDirectory(spec.name)),
|
||||||
|
serviceName = spec.name,
|
||||||
|
serviceId = "identity")
|
||||||
|
} else {
|
||||||
|
ServiceIdentityGenerator.generateToDisk(
|
||||||
|
dirs = generateNodeNames(spec).map { baseDirectory(it) },
|
||||||
|
serviceName = spec.name,
|
||||||
|
serviceId = NotaryService.constructId(
|
||||||
|
validating = spec.validating,
|
||||||
|
raft = spec.cluster is ClusterSpec.Raft))
|
||||||
|
}
|
||||||
|
NotaryInfo(identity, spec.validating)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateNodeNames(spec: NotarySpec): List<CordaX500Name> {
|
||||||
|
return (0 until spec.cluster!!.clusterSize).map { spec.name.copy(organisation = "${spec.name.organisation}-$it") }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startNotaries(): List<CordaFuture<List<NodeHandle>>> {
|
||||||
|
return notarySpecs.map {
|
||||||
|
when {
|
||||||
|
it.cluster == null -> startSingleNotary(it)
|
||||||
|
it.cluster is ClusterSpec.Raft -> startRaftNotaryCluster(it)
|
||||||
|
else -> throw IllegalArgumentException("BFT-SMaRt not supported")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO This mapping is done is several places including the gradle plugin. In general we need a better way of
|
||||||
|
// generating the configs for the nodes, probably making use of Any.toConfig()
|
||||||
|
private fun NotaryConfig.toConfigMap(): Map<String, Any> = mapOf("notary" to toConfig().root().unwrapped())
|
||||||
|
|
||||||
|
private fun startSingleNotary(spec: NotarySpec): CordaFuture<List<NodeHandle>> {
|
||||||
|
return startNode(
|
||||||
|
providedName = spec.name,
|
||||||
|
rpcUsers = spec.rpcUsers,
|
||||||
|
verifierType = spec.verifierType,
|
||||||
|
customOverrides = NotaryConfig(spec.validating).toConfigMap()
|
||||||
|
).map { listOf(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startRaftNotaryCluster(spec: NotarySpec): CordaFuture<List<NodeHandle>> {
|
||||||
|
fun notaryConfig(nodeAddress: NetworkHostAndPort, clusterAddress: NetworkHostAndPort? = null): Map<String, Any> {
|
||||||
|
val clusterAddresses = if (clusterAddress != null) listOf(clusterAddress) else emptyList()
|
||||||
|
val config = NotaryConfig(
|
||||||
|
validating = spec.validating,
|
||||||
|
raft = RaftConfig(nodeAddress = nodeAddress, clusterAddresses = clusterAddresses))
|
||||||
|
return config.toConfigMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
val nodeNames = generateNodeNames(spec)
|
||||||
|
val clusterAddress = portAllocation.nextHostAndPort()
|
||||||
|
|
||||||
|
// Start the first node that will bootstrap the cluster
|
||||||
|
val firstNodeFuture = startNode(
|
||||||
|
providedName = nodeNames[0],
|
||||||
|
rpcUsers = spec.rpcUsers,
|
||||||
|
verifierType = spec.verifierType,
|
||||||
|
customOverrides = notaryConfig(clusterAddress) + mapOf(
|
||||||
|
"database.serverNameTablePrefix" to nodeNames[0].toString().replace(Regex("[^0-9A-Za-z]+"), "")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// All other nodes will join the cluster
|
||||||
|
val restNodeFutures = nodeNames.drop(1).map {
|
||||||
|
val nodeAddress = portAllocation.nextHostAndPort()
|
||||||
|
startNode(
|
||||||
|
providedName = it,
|
||||||
|
rpcUsers = spec.rpcUsers,
|
||||||
|
verifierType = spec.verifierType,
|
||||||
|
customOverrides = notaryConfig(nodeAddress, clusterAddress) + mapOf(
|
||||||
|
"database.serverNameTablePrefix" to it.toString().replace(Regex("[^0-9A-Za-z]+"), "")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstNodeFuture.flatMap { first ->
|
||||||
|
restNodeFutures.transpose().map { rest -> listOf(first) + rest }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun baseDirectory(nodeName: CordaX500Name): Path {
|
fun baseDirectory(nodeName: CordaX500Name): Path {
|
||||||
@ -925,10 +963,7 @@ class DriverDSL(
|
|||||||
maximumHeapSize: String): CordaFuture<NodeHandle> {
|
maximumHeapSize: String): CordaFuture<NodeHandle> {
|
||||||
val configuration = config.parseAsNodeConfiguration()
|
val configuration = config.parseAsNodeConfiguration()
|
||||||
val baseDirectory = configuration.baseDirectory.createDirectories()
|
val baseDirectory = configuration.baseDirectory.createDirectories()
|
||||||
if (networkParameters == null) {
|
networkParameters.install(baseDirectory)
|
||||||
networkParameters = NetworkParametersCopier(testNetworkParameters(emptyList()))
|
|
||||||
}
|
|
||||||
networkParameters!!.install(baseDirectory)
|
|
||||||
nodeInfoFilesCopier.addConfig(baseDirectory)
|
nodeInfoFilesCopier.addConfig(baseDirectory)
|
||||||
val onNodeExit: () -> Unit = {
|
val onNodeExit: () -> Unit = {
|
||||||
nodeInfoFilesCopier.removeConfig(baseDirectory)
|
nodeInfoFilesCopier.removeConfig(baseDirectory)
|
||||||
|
@ -7,6 +7,7 @@ import com.nhaarman.mockito_kotlin.whenever
|
|||||||
import net.corda.core.crypto.entropyToKeyPair
|
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.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
|
||||||
@ -110,6 +111,9 @@ data class MockNodeArgs(
|
|||||||
* You can get a printout of every message sent by using code like:
|
* You can get a printout of every message sent by using code like:
|
||||||
*
|
*
|
||||||
* LogHelper.setLevel("+messages")
|
* LogHelper.setLevel("+messages")
|
||||||
|
*
|
||||||
|
* By default a single notary node is automatically started, which forms part of the network parameters for all the nodes.
|
||||||
|
* This node is available by calling [defaultNotaryNode].
|
||||||
*/
|
*/
|
||||||
class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParameters(),
|
class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParameters(),
|
||||||
private val networkSendManuallyPumped: Boolean = defaultParameters.networkSendManuallyPumped,
|
private val networkSendManuallyPumped: Boolean = defaultParameters.networkSendManuallyPumped,
|
||||||
@ -117,6 +121,7 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
|
|||||||
servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy,
|
servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy,
|
||||||
private val defaultFactory: (MockNodeArgs) -> MockNode = defaultParameters.defaultFactory,
|
private val defaultFactory: (MockNodeArgs) -> MockNode = defaultParameters.defaultFactory,
|
||||||
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
|
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
|
||||||
|
private val notarySpecs: List<NotarySpec> = listOf(NotarySpec(DUMMY_NOTARY.name)),
|
||||||
private val cordappPackages: List<String> = defaultParameters.cordappPackages) : Closeable {
|
private val cordappPackages: List<String> = defaultParameters.cordappPackages) : Closeable {
|
||||||
/** Helper constructor for creating a [MockNetwork] with custom parameters from Java. */
|
/** Helper constructor for creating a [MockNetwork] with custom parameters from Java. */
|
||||||
constructor(parameters: MockNetworkParameters) : this(defaultParameters = parameters)
|
constructor(parameters: MockNetworkParameters) : this(defaultParameters = parameters)
|
||||||
@ -128,22 +133,43 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
|
|||||||
val messagingNetwork = InMemoryMessagingNetwork(networkSendManuallyPumped, servicePeerAllocationStrategy, busyLatch)
|
val messagingNetwork = InMemoryMessagingNetwork(networkSendManuallyPumped, servicePeerAllocationStrategy, busyLatch)
|
||||||
// A unique identifier for this network to segregate databases with the same nodeID but different networks.
|
// A unique identifier for this network to segregate databases with the same nodeID but different networks.
|
||||||
private val networkId = random63BitValue()
|
private val networkId = random63BitValue()
|
||||||
private lateinit var networkParameters: NetworkParametersCopier
|
private val networkParameters: NetworkParametersCopier
|
||||||
private var notaryInfos: MutableList<NotaryInfo>? = ArrayList()
|
private val _nodes = mutableListOf<MockNode>()
|
||||||
private val _nodes = ArrayList<MockNode>()
|
|
||||||
private val serializationEnv = initialiseTestSerialization(initialiseSerialization)
|
private val serializationEnv = initialiseTestSerialization(initialiseSerialization)
|
||||||
|
private val sharedUserCount = AtomicInteger(0)
|
||||||
|
|
||||||
/** A read only view of the current set of executing nodes. */
|
/** A read only view of the current set of executing nodes. */
|
||||||
val nodes: List<MockNode> get() = _nodes
|
val nodes: List<MockNode> get() = _nodes
|
||||||
|
|
||||||
init {
|
/**
|
||||||
filesystem.getPath("/nodes").createDirectory()
|
* Returns the list of nodes started by the network. Each notary specified when the network is constructed ([notarySpecs]
|
||||||
|
* parameter) maps 1:1 to the notaries returned by this list.
|
||||||
|
*/
|
||||||
|
val notaryNodes: List<StartedNode<MockNode>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the single notary node on the network. Throws if there are none or more than one.
|
||||||
|
* @see notaryNodes
|
||||||
|
*/
|
||||||
|
val defaultNotaryNode: StartedNode<MockNode> get() {
|
||||||
|
return when (notaryNodes.size) {
|
||||||
|
0 -> throw IllegalStateException("There are no notaries defined on the network")
|
||||||
|
1 -> notaryNodes[0]
|
||||||
|
else -> throw IllegalStateException("There is more than one notary defined on the network")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the identity of the default notary node.
|
||||||
|
* @see defaultNotaryNode
|
||||||
|
*/
|
||||||
|
val defaultNotaryIdentity: Party get() {
|
||||||
|
return defaultNotaryNode.info.legalIdentities.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.
|
||||||
*/
|
*/
|
||||||
private val sharedUserCount = AtomicInteger(0)
|
|
||||||
private val sharedServerThread = object : ServiceAffinityExecutor("Mock network", 1) {
|
private val sharedServerThread = object : ServiceAffinityExecutor("Mock network", 1) {
|
||||||
override fun shutdown() {
|
override fun shutdown() {
|
||||||
// We don't actually allow the shutdown of the network-wide shared thread pool until all references to
|
// We don't actually allow the shutdown of the network-wide shared thread pool until all references to
|
||||||
@ -163,6 +189,32 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
filesystem.getPath("/nodes").createDirectory()
|
||||||
|
val notaryInfos = generateNotaryIdentities()
|
||||||
|
// The network parameters must be serialised before starting any of the nodes
|
||||||
|
networkParameters = NetworkParametersCopier(testNetworkParameters(notaryInfos))
|
||||||
|
notaryNodes = createNotaries()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateNotaryIdentities(): List<NotaryInfo> {
|
||||||
|
return notarySpecs.mapIndexed { index, spec ->
|
||||||
|
val identity = ServiceIdentityGenerator.generateToDisk(
|
||||||
|
dirs = listOf(baseDirectory(nextNodeId + index)),
|
||||||
|
serviceName = spec.name,
|
||||||
|
serviceId = "identity")
|
||||||
|
NotaryInfo(identity, spec.validating)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNotaries(): List<StartedNode<MockNode>> {
|
||||||
|
return notarySpecs.map { spec ->
|
||||||
|
createNode(MockNodeParameters(legalName = spec.name, configOverrides = {
|
||||||
|
doReturn(NotaryConfig(spec.validating)).whenever(it).notary
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open class MockNode(args: MockNodeArgs) : AbstractNode(
|
open class MockNode(args: MockNodeArgs) : AbstractNode(
|
||||||
args.config,
|
args.config,
|
||||||
TestClock(),
|
TestClock(),
|
||||||
@ -188,20 +240,12 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
|
|||||||
override val started: StartedNode<MockNode>? get() = uncheckedCast(super.started)
|
override val started: StartedNode<MockNode>? get() = uncheckedCast(super.started)
|
||||||
|
|
||||||
override fun start(): StartedNode<MockNode> {
|
override fun start(): StartedNode<MockNode> {
|
||||||
installNetworkParameters()
|
mockNet.networkParameters.install(configuration.baseDirectory)
|
||||||
val started: StartedNode<MockNode> = uncheckedCast(super.start())
|
val started: StartedNode<MockNode> = uncheckedCast(super.start())
|
||||||
advertiseNodeToNetwork(started)
|
advertiseNodeToNetwork(started)
|
||||||
return started
|
return started
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun installNetworkParameters() {
|
|
||||||
mockNet.notaryInfos?.let {
|
|
||||||
mockNet.networkParameters = NetworkParametersCopier(testNetworkParameters(it))
|
|
||||||
}
|
|
||||||
mockNet.notaryInfos = null
|
|
||||||
mockNet.networkParameters.install(configuration.baseDirectory)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun advertiseNodeToNetwork(newNode: StartedNode<MockNode>) {
|
private fun advertiseNodeToNetwork(newNode: StartedNode<MockNode>) {
|
||||||
mockNet.nodes
|
mockNet.nodes
|
||||||
.mapNotNull { it.started }
|
.mapNotNull { it.started }
|
||||||
@ -273,9 +317,6 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
|
|||||||
dbCloser = null
|
dbCloser = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasDBConnection() = dbCloser != null
|
|
||||||
|
|
||||||
// You can change this from zero if you have custom [FlowLogic] that park themselves. e.g. [StateMachineManagerTests]
|
|
||||||
var acceptableLiveFiberCountOnStop: Int = 0
|
var acceptableLiveFiberCountOnStop: Int = 0
|
||||||
|
|
||||||
override fun acceptableLiveFiberCountOnStop(): Int = acceptableLiveFiberCountOnStop
|
override fun acceptableLiveFiberCountOnStop(): Int = acceptableLiveFiberCountOnStop
|
||||||
@ -321,23 +362,11 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
|
|||||||
doReturn(makeTestDataSourceProperties("node_${id}_net_$networkId")).whenever(it).dataSourceProperties
|
doReturn(makeTestDataSourceProperties("node_${id}_net_$networkId")).whenever(it).dataSourceProperties
|
||||||
parameters.configOverrides(it)
|
parameters.configOverrides(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
val node = nodeFactory(MockNodeArgs(config, this, id, parameters.entropyRoot))
|
val node = nodeFactory(MockNodeArgs(config, this, id, parameters.entropyRoot))
|
||||||
_nodes += node
|
_nodes += node
|
||||||
|
|
||||||
config.notary?.let { notaryConfig ->
|
|
||||||
val notaryInfos = notaryInfos ?: throw IllegalStateException("Cannot add notaries once nodes have started")
|
|
||||||
if (!notaryConfig.isClusterConfig) {
|
|
||||||
// Create the node's main identity, which will also double as its notary identity
|
|
||||||
val identity = ServiceIdentityGenerator.generateToDisk(listOf(config.baseDirectory), config.myLegalName, "identity")
|
|
||||||
notaryInfos += NotaryInfo(identity, notaryConfig.validating)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start) {
|
if (start) {
|
||||||
node.start()
|
node.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,24 +394,7 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun createNotaryNode(parameters: MockNodeParameters = MockNodeParameters(legalName = DUMMY_NOTARY.name),
|
|
||||||
validating: Boolean = true): StartedNode<MockNode> {
|
|
||||||
return createNotaryNode(parameters, validating, defaultFactory)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <N : MockNode> createNotaryNode(parameters: MockNodeParameters = MockNodeParameters(legalName = DUMMY_NOTARY.name),
|
|
||||||
validating: Boolean = true,
|
|
||||||
nodeFactory: (MockNodeArgs) -> N): StartedNode<N> {
|
|
||||||
return createNode(
|
|
||||||
parameters.copy(configOverrides = {
|
|
||||||
doReturn(NotaryConfig(validating)).whenever(it).notary
|
|
||||||
parameters.configOverrides(it)
|
|
||||||
}),
|
|
||||||
nodeFactory
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmOverloads
|
|
||||||
fun createPartyNode(legalName: CordaX500Name? = null): StartedNode<MockNode> {
|
fun createPartyNode(legalName: CordaX500Name? = null): StartedNode<MockNode> {
|
||||||
return createNode(MockNodeParameters(legalName = legalName))
|
return createNode(MockNodeParameters(legalName = legalName))
|
||||||
}
|
}
|
||||||
@ -418,14 +430,16 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
|
|||||||
override fun close() {
|
override fun close() {
|
||||||
stopNodes()
|
stopNodes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class NotarySpec(val name: CordaX500Name, val validating: Boolean = true) {
|
||||||
|
constructor(name: CordaX500Name) : this(name, validating = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun network(nodesCount: Int, action: MockNetwork.(nodes: List<StartedNode<MockNetwork.MockNode>>, notary: StartedNode<MockNetwork.MockNode>) -> Unit) {
|
fun network(nodesCount: Int, action: MockNetwork.(List<StartedNode<MockNetwork.MockNode>>) -> Unit) {
|
||||||
MockNetwork().use {
|
MockNetwork().use { mockNet ->
|
||||||
it.runNetwork()
|
val nodes = (1..nodesCount).map { mockNet.createPartyNode() }
|
||||||
val notary = it.createNotaryNode()
|
mockNet.action(nodes)
|
||||||
val nodes = (1..nodesCount).map { _ -> it.createPartyNode() }
|
|
||||||
action(it, nodes, notary)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package net.corda.testing.node
|
||||||
|
|
||||||
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import net.corda.node.services.config.VerifierType
|
||||||
|
import net.corda.nodeapi.User
|
||||||
|
|
||||||
|
data class NotarySpec(
|
||||||
|
val name: CordaX500Name,
|
||||||
|
val validating: Boolean = true,
|
||||||
|
val rpcUsers: List<User> = emptyList(),
|
||||||
|
val verifierType: VerifierType = VerifierType.InMemory,
|
||||||
|
val cluster: ClusterSpec? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
sealed class ClusterSpec {
|
||||||
|
abstract val clusterSize: Int
|
||||||
|
|
||||||
|
data class Raft(override val clusterSize: Int) : ClusterSpec() {
|
||||||
|
init {
|
||||||
|
require(clusterSize > 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,14 +24,13 @@ import net.corda.node.services.Permissions.Companion.startFlow
|
|||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.ALICE
|
import net.corda.testing.ALICE
|
||||||
import net.corda.testing.BOB
|
import net.corda.testing.BOB
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.PortAllocation
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ExplorerSimulation(val options: OptionSet) {
|
class ExplorerSimulation(private val options: OptionSet) {
|
||||||
private val user = User("user1", "test", permissions = setOf(
|
private val user = User("user1", "test", permissions = setOf(
|
||||||
startFlow<CashPaymentFlow>(),
|
startFlow<CashPaymentFlow>(),
|
||||||
startFlow<CashConfigDataFlow>()
|
startFlow<CashConfigDataFlow>()
|
||||||
@ -67,23 +66,16 @@ class ExplorerSimulation(val options: OptionSet) {
|
|||||||
val portAllocation = PortAllocation.Incremental(20000)
|
val portAllocation = PortAllocation.Incremental(20000)
|
||||||
driver(portAllocation = portAllocation, extraCordappPackagesToScan = listOf("net.corda.finance")) {
|
driver(portAllocation = portAllocation, extraCordappPackagesToScan = listOf("net.corda.finance")) {
|
||||||
// TODO : Supported flow should be exposed somehow from the node instead of set of ServiceInfo.
|
// TODO : Supported flow should be exposed somehow from the node instead of set of ServiceInfo.
|
||||||
val notary = startNotaryNode(DUMMY_NOTARY.name, customOverrides = mapOf("nearestCity" to "Zurich"), validating = false)
|
val alice = startNode(providedName = ALICE.name, rpcUsers = listOf(user))
|
||||||
val alice = startNode(providedName = ALICE.name, rpcUsers = arrayListOf(user),
|
val bob = startNode(providedName = BOB.name, rpcUsers = listOf(user))
|
||||||
customOverrides = mapOf("nearestCity" to "Milan"))
|
|
||||||
val bob = startNode(providedName = BOB.name, rpcUsers = arrayListOf(user),
|
|
||||||
customOverrides = mapOf("nearestCity" to "Madrid"))
|
|
||||||
val ukBankName = CordaX500Name(organisation = "UK Bank Plc", locality = "London", country = "GB")
|
val ukBankName = CordaX500Name(organisation = "UK Bank Plc", locality = "London", country = "GB")
|
||||||
val usaBankName = CordaX500Name(organisation = "USA Bank Corp", locality = "New York", country = "US")
|
val usaBankName = CordaX500Name(organisation = "USA Bank Corp", locality = "New York", country = "US")
|
||||||
val issuerGBP = startNode(providedName = ukBankName, rpcUsers = arrayListOf(manager),
|
val issuerGBP = startNode(providedName = ukBankName, rpcUsers = listOf(manager),
|
||||||
customOverrides = mapOf(
|
customOverrides = mapOf("issuableCurrencies" to listOf("GBP")))
|
||||||
"issuableCurrencies" to listOf("GBP"),
|
val issuerUSD = startNode(providedName = usaBankName, rpcUsers = listOf(manager),
|
||||||
"nearestCity" to "London"))
|
customOverrides = mapOf("issuableCurrencies" to listOf("USD")))
|
||||||
val issuerUSD = startNode(providedName = usaBankName, rpcUsers = arrayListOf(manager),
|
|
||||||
customOverrides = mapOf(
|
|
||||||
"issuableCurrencies" to listOf("USD"),
|
|
||||||
"nearestCity" to "New York"))
|
|
||||||
|
|
||||||
notaryNode = notary.get()
|
notaryNode = defaultNotaryNode.get()
|
||||||
aliceNode = alice.get()
|
aliceNode = alice.get()
|
||||||
bobNode = bob.get()
|
bobNode = bob.get()
|
||||||
issuerNodeGBP = issuerGBP.get()
|
issuerNodeGBP = issuerGBP.get()
|
||||||
|
@ -19,6 +19,7 @@ import net.corda.nodeapi.VerifierApi
|
|||||||
import net.corda.nodeapi.config.NodeSSLConfiguration
|
import net.corda.nodeapi.config.NodeSSLConfiguration
|
||||||
import net.corda.nodeapi.config.SSLConfiguration
|
import net.corda.nodeapi.config.SSLConfiguration
|
||||||
import net.corda.testing.driver.*
|
import net.corda.testing.driver.*
|
||||||
|
import net.corda.testing.node.NotarySpec
|
||||||
import org.apache.activemq.artemis.api.core.SimpleString
|
import org.apache.activemq.artemis.api.core.SimpleString
|
||||||
import org.apache.activemq.artemis.api.core.client.ActiveMQClient
|
import org.apache.activemq.artemis.api.core.client.ActiveMQClient
|
||||||
import org.apache.activemq.artemis.api.core.client.ClientProducer
|
import org.apache.activemq.artemis.api.core.client.ClientProducer
|
||||||
@ -77,6 +78,7 @@ fun <A> verifierDriver(
|
|||||||
useTestClock: Boolean = false,
|
useTestClock: Boolean = false,
|
||||||
startNodesInProcess: Boolean = false,
|
startNodesInProcess: Boolean = false,
|
||||||
extraCordappPackagesToScan: List<String> = emptyList(),
|
extraCordappPackagesToScan: List<String> = emptyList(),
|
||||||
|
notarySpecs: List<NotarySpec> = emptyList(),
|
||||||
dsl: VerifierExposedDSLInterface.() -> A
|
dsl: VerifierExposedDSLInterface.() -> A
|
||||||
) = genericDriver(
|
) = genericDriver(
|
||||||
driverDsl = VerifierDriverDSL(
|
driverDsl = VerifierDriverDSL(
|
||||||
@ -88,7 +90,8 @@ fun <A> verifierDriver(
|
|||||||
useTestClock = useTestClock,
|
useTestClock = useTestClock,
|
||||||
isDebug = isDebug,
|
isDebug = isDebug,
|
||||||
startNodesInProcess = startNodesInProcess,
|
startNodesInProcess = startNodesInProcess,
|
||||||
extraCordappPackagesToScan = extraCordappPackagesToScan
|
extraCordappPackagesToScan = extraCordappPackagesToScan,
|
||||||
|
notarySpecs = notarySpecs
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
coerce = { it },
|
coerce = { it },
|
||||||
|
@ -15,6 +15,7 @@ import net.corda.node.services.config.VerifierType
|
|||||||
import net.corda.testing.ALICE
|
import net.corda.testing.ALICE
|
||||||
import net.corda.testing.ALICE_NAME
|
import net.corda.testing.ALICE_NAME
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
import net.corda.testing.DUMMY_NOTARY
|
||||||
|
import net.corda.testing.node.NotarySpec
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
@ -128,15 +129,15 @@ class VerifierTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `single verifier works with a node`() {
|
fun `single verifier works with a node`() {
|
||||||
verifierDriver(extraCordappPackagesToScan = listOf("net.corda.finance.contracts")) {
|
verifierDriver(
|
||||||
val (notaryNode, aliceNode) = listOf(
|
extraCordappPackagesToScan = listOf("net.corda.finance.contracts"),
|
||||||
startNotaryNode(DUMMY_NOTARY.name, verifierType = VerifierType.OutOfProcess),
|
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name, verifierType = VerifierType.OutOfProcess))
|
||||||
startNode(providedName = ALICE.name)
|
) {
|
||||||
).transpose().getOrThrow()
|
val aliceNode = startNode(providedName = ALICE.name).getOrThrow()
|
||||||
|
val notaryNode = defaultNotaryNode.getOrThrow()
|
||||||
val alice = aliceNode.rpc.wellKnownPartyFromX500Name(ALICE_NAME)!!
|
val alice = aliceNode.rpc.wellKnownPartyFromX500Name(ALICE_NAME)!!
|
||||||
val notary = notaryNode.rpc.notaryPartyFromX500Name(DUMMY_NOTARY.name)!!
|
|
||||||
startVerifier(notaryNode)
|
startVerifier(notaryNode)
|
||||||
aliceNode.rpc.startFlow(::CashIssueFlow, 10.DOLLARS, OpaqueBytes.of(0), notary).returnValue.get()
|
aliceNode.rpc.startFlow(::CashIssueFlow, 10.DOLLARS, OpaqueBytes.of(0), defaultNotaryIdentity).returnValue.get()
|
||||||
notaryNode.waitUntilNumberOfVerifiers(1)
|
notaryNode.waitUntilNumberOfVerifiers(1)
|
||||||
for (i in 1..10) {
|
for (i in 1..10) {
|
||||||
val cashFlowResult = aliceNode.rpc.startFlow(::CashPaymentFlow, 10.DOLLARS, alice).returnValue.get()
|
val cashFlowResult = aliceNode.rpc.startFlow(::CashPaymentFlow, 10.DOLLARS, alice).returnValue.get()
|
||||||
|
@ -11,7 +11,7 @@ import org.junit.Test
|
|||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.ScheduledExecutorService
|
import java.util.concurrent.ScheduledExecutorService
|
||||||
|
|
||||||
class DriverTests {
|
class WebserverDriverTests {
|
||||||
companion object {
|
companion object {
|
||||||
val executorService: ScheduledExecutorService = Executors.newScheduledThreadPool(2)
|
val executorService: ScheduledExecutorService = Executors.newScheduledThreadPool(2)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user