diff --git a/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java b/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java index 00cefb9cc0..a555f9c69a 100644 --- a/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java +++ b/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java @@ -18,8 +18,8 @@ import net.corda.finance.flows.AbstractCashFlow; import net.corda.finance.flows.CashIssueFlow; import net.corda.finance.flows.CashPaymentFlow; import net.corda.finance.schemas.CashSchemaV1; -import net.corda.node.internal.Node; import net.corda.node.internal.StartedNode; +import net.corda.node.internal.StartedNodeWithInternals; import net.corda.testing.internal.InternalTestUtilsKt; import net.corda.testing.node.User; import net.corda.testing.internal.IntegrationTestKt; @@ -60,7 +60,7 @@ public class CordaRPCJavaClientTest extends NodeBasedTest { private Set permSet = new HashSet<>(perms); private User rpcUser = new User("user1", "test", permSet); - private StartedNode node; + private StartedNodeWithInternals node; private CordaRPCClient client; private RPCConnection connection = null; private CordaRPCOps rpcProxy; diff --git a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt index f47917197d..c7aad8a7b1 100644 --- a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt +++ b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt @@ -30,8 +30,7 @@ import net.corda.finance.contracts.getCashBalance import net.corda.finance.contracts.getCashBalances import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow -import net.corda.node.internal.Node -import net.corda.node.internal.StartedNode +import net.corda.node.internal.StartedNodeWithInternals import net.corda.node.services.Permissions.Companion.all import net.corda.testing.common.internal.checkNotOnClasspath import net.corda.testing.core.* @@ -68,7 +67,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance")) { val databaseSchemas = IntegrationTestSchemas(ALICE_NAME.toDatabaseSchemaName()) } - private lateinit var node: StartedNode + private lateinit var node: StartedNodeWithInternals private lateinit var identity: Party private lateinit var client: CordaRPCClient private var connection: CordaRPCConnection? = null diff --git a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt index 25aa097da7..e9b56eeadf 100644 --- a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt +++ b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt @@ -16,8 +16,7 @@ import net.corda.core.internal.packageName import net.corda.core.messaging.CordaRPCOps import net.corda.core.utilities.getOrThrow import net.corda.finance.schemas.CashSchemaV1 -import net.corda.node.internal.Node -import net.corda.node.internal.StartedNode +import net.corda.node.internal.StartedNodeWithInternals import net.corda.node.services.Permissions import net.corda.node.services.Permissions.Companion.invokeRpc import net.corda.testing.core.ALICE_NAME @@ -79,7 +78,7 @@ class FlowsExecutionModeTests : NodeBasedTest(listOf("net.corda.finance.contract } private val rpcUser = User("user1", "test", permissions = setOf(Permissions.all())) - private lateinit var node: StartedNode + private lateinit var node: StartedNodeWithInternals private lateinit var client: CordaRPCClient @Before diff --git a/core/src/main/java/net/corda/core/crypto/Base58.java b/core/src/main/java/net/corda/core/crypto/Base58.java index e7953d1596..9831a63f05 100644 --- a/core/src/main/java/net/corda/core/crypto/Base58.java +++ b/core/src/main/java/net/corda/core/crypto/Base58.java @@ -11,8 +11,9 @@ package net.corda.core.crypto; import net.corda.core.KeepForDJVM; -import java.math.*; -import java.util.*; + +import java.math.BigInteger; +import java.util.Arrays; /** * Base58 is a way to encode Bitcoin addresses (or arbitrary data) as alphanumeric strings. diff --git a/core/src/main/kotlin/net/corda/core/CordaInternal.kt b/core/src/main/kotlin/net/corda/core/CordaInternal.kt index f9e8342390..2e39c4f81e 100644 --- a/core/src/main/kotlin/net/corda/core/CordaInternal.kt +++ b/core/src/main/kotlin/net/corda/core/CordaInternal.kt @@ -10,7 +10,7 @@ package net.corda.core -import kotlin.annotation.AnnotationRetention.* +import kotlin.annotation.AnnotationRetention.BINARY import kotlin.annotation.AnnotationTarget.* /** diff --git a/core/src/main/kotlin/net/corda/core/DeleteForDJVM.kt b/core/src/main/kotlin/net/corda/core/DeleteForDJVM.kt index 36f94ac707..b4b92d1df8 100644 --- a/core/src/main/kotlin/net/corda/core/DeleteForDJVM.kt +++ b/core/src/main/kotlin/net/corda/core/DeleteForDJVM.kt @@ -1,9 +1,7 @@ package net.corda.core -import kotlin.annotation.AnnotationRetention.* +import kotlin.annotation.AnnotationRetention.BINARY import kotlin.annotation.AnnotationTarget.* -import kotlin.annotation.Retention -import kotlin.annotation.Target /** * Declare the annotated element to unsuitable for the deterministic version of Corda. diff --git a/core/src/main/kotlin/net/corda/core/KeepForDJVM.kt b/core/src/main/kotlin/net/corda/core/KeepForDJVM.kt index 0b25143247..beaa8281be 100644 --- a/core/src/main/kotlin/net/corda/core/KeepForDJVM.kt +++ b/core/src/main/kotlin/net/corda/core/KeepForDJVM.kt @@ -1,9 +1,8 @@ package net.corda.core -import kotlin.annotation.AnnotationRetention.* -import kotlin.annotation.AnnotationTarget.* -import kotlin.annotation.Retention -import kotlin.annotation.Target +import kotlin.annotation.AnnotationRetention.BINARY +import kotlin.annotation.AnnotationTarget.CLASS +import kotlin.annotation.AnnotationTarget.FILE /** * This annotates a class or file that we want to include into the deterministic version of Corda Core. diff --git a/core/src/main/kotlin/net/corda/core/StubOutForDJVM.kt b/core/src/main/kotlin/net/corda/core/StubOutForDJVM.kt index d5e3fe7c5a..c38c38569a 100644 --- a/core/src/main/kotlin/net/corda/core/StubOutForDJVM.kt +++ b/core/src/main/kotlin/net/corda/core/StubOutForDJVM.kt @@ -1,9 +1,7 @@ package net.corda.core -import kotlin.annotation.AnnotationRetention.* +import kotlin.annotation.AnnotationRetention.BINARY import kotlin.annotation.AnnotationTarget.* -import kotlin.annotation.Retention -import kotlin.annotation.Target /** * We expect that almost every non-deterministic element can have its bytecode diff --git a/core/src/main/kotlin/net/corda/core/concurrent/ConcurrencyUtils.kt b/core/src/main/kotlin/net/corda/core/concurrent/ConcurrencyUtils.kt index 12fa8e806b..0515c2311c 100644 --- a/core/src/main/kotlin/net/corda/core/concurrent/ConcurrencyUtils.kt +++ b/core/src/main/kotlin/net/corda/core/concurrent/ConcurrencyUtils.kt @@ -11,9 +11,9 @@ @file:JvmName("ConcurrencyUtils") package net.corda.core.concurrent +import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.concurrent.openFuture import net.corda.core.utilities.getOrThrow -import net.corda.core.internal.VisibleForTesting import org.slf4j.Logger import org.slf4j.LoggerFactory import java.util.concurrent.Future diff --git a/core/src/main/kotlin/net/corda/core/identity/CordaX500Name.kt b/core/src/main/kotlin/net/corda/core/identity/CordaX500Name.kt index 535e659ec7..34412bcdca 100644 --- a/core/src/main/kotlin/net/corda/core/identity/CordaX500Name.kt +++ b/core/src/main/kotlin/net/corda/core/identity/CordaX500Name.kt @@ -13,8 +13,8 @@ package net.corda.core.identity import net.corda.core.KeepForDJVM import net.corda.core.internal.LegalNameValidator import net.corda.core.internal.toAttributesMap -import net.corda.core.internal.unspecifiedCountry import net.corda.core.internal.toX500Name +import net.corda.core.internal.unspecifiedCountry import net.corda.core.serialization.CordaSerializable import org.bouncycastle.asn1.x500.style.BCStyle import java.util.* diff --git a/core/src/main/kotlin/net/corda/core/internal/concurrent/CordaFutureImpl.kt b/core/src/main/kotlin/net/corda/core/internal/concurrent/CordaFutureImpl.kt index 467b65285e..672f272b12 100644 --- a/core/src/main/kotlin/net/corda/core/internal/concurrent/CordaFutureImpl.kt +++ b/core/src/main/kotlin/net/corda/core/internal/concurrent/CordaFutureImpl.kt @@ -10,9 +10,9 @@ package net.corda.core.internal.concurrent -import net.corda.core.internal.VisibleForTesting import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.match +import net.corda.core.internal.VisibleForTesting import net.corda.core.utilities.contextLogger import net.corda.core.utilities.getOrThrow import org.slf4j.Logger diff --git a/core/src/test/java/net/corda/core/concurrent/CordaFutureInJavaTest.java b/core/src/test/java/net/corda/core/concurrent/CordaFutureInJavaTest.java index 2896726aeb..72e8b6636c 100644 --- a/core/src/test/java/net/corda/core/concurrent/CordaFutureInJavaTest.java +++ b/core/src/test/java/net/corda/core/concurrent/CordaFutureInJavaTest.java @@ -14,18 +14,12 @@ import net.corda.core.internal.concurrent.OpenFuture; import org.junit.Test; import java.io.EOFException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.util.concurrent.*; import static net.corda.core.internal.concurrent.CordaFutureImplKt.doneFuture; import static net.corda.core.internal.concurrent.CordaFutureImplKt.openFuture; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; public class CordaFutureInJavaTest { @Test diff --git a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt index 08ee35f08d..42060a4f54 100644 --- a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt @@ -158,18 +158,18 @@ class AttachmentTests : WithMockNet { //endregion //region Operations - private fun StartedNode<*>.importAttachment(attachment: ByteArray) = + private fun StartedNode.importAttachment(attachment: ByteArray) = attachments.importAttachment(attachment.inputStream(), "test", null) .andRunNetwork() - private fun StartedNode<*>.updateAttachment(attachment: NodeAttachmentService.DBAttachment) = database.transaction { + private fun StartedNode.updateAttachment(attachment: NodeAttachmentService.DBAttachment) = database.transaction { session.update(attachment) }.andRunNetwork() - private fun StartedNode<*>.startAttachmentFlow(hash: SecureHash, otherSide: Party) = startFlowAndRunNetwork( + private fun StartedNode.startAttachmentFlow(hash: SecureHash, otherSide: Party) = startFlowAndRunNetwork( InitiatingFetchAttachmentsFlow(otherSide, setOf(hash))) - private fun StartedNode<*>.getAttachmentWithId(id: SecureHash) = + private fun StartedNode.getAttachmentWithId(id: SecureHash) = attachments.openAttachment(id)!! //endregion diff --git a/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt index 55d52554eb..61a907dd4d 100644 --- a/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt @@ -103,7 +103,7 @@ class CollectSignaturesFlowTests : WithContracts { } //region Operators - private fun StartedNode<*>.startTestFlow(vararg party: Party) = + private fun StartedNode.startTestFlow(vararg party: Party) = startFlowAndRunNetwork( TestFlow.Initiator(DummyContract.MultiOwnerState( MAGIC_NUMBER, diff --git a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowRPCTest.kt b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowRPCTest.kt index a6095f1162..7e006f1d5c 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowRPCTest.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowRPCTest.kt @@ -24,7 +24,6 @@ import net.corda.testing.core.BOB_NAME import net.corda.testing.core.singleIdentity import net.corda.testing.node.User import net.corda.testing.node.internal.* -import net.corda.testing.node.internal.InternalMockNetwork.MockNode import org.junit.AfterClass import org.junit.Test @@ -85,7 +84,7 @@ class ContractUpgradeFlowRPCTest : WithContracts, WithFinality { } //region RPC DSL - private fun RPCDriverDSL.startProxy(node: StartedNode, user: User): CordaRPCOps { + private fun RPCDriverDSL.startProxy(node: StartedNode, user: User): CordaRPCOps { return startRpcClient( rpcAddress = startRpcServer( rpcUser = user, @@ -113,16 +112,16 @@ class ContractUpgradeFlowRPCTest : WithContracts, WithFinality { //endregion //region Matchers - private fun StartedNode<*>.hasDummyContractUpgradeTransaction() = + private fun StartedNode.hasDummyContractUpgradeTransaction() = hasContractUpgradeTransaction() - private inline fun StartedNode<*>.hasContractUpgradeTransaction() = + private inline fun StartedNode.hasContractUpgradeTransaction() = has, ContractUpgradeLedgerTransaction>( "a contract upgrade transaction", { getContractUpgradeTransaction(it) }, isUpgrade()) - private fun StartedNode<*>.getContractUpgradeTransaction(state: StateAndRef) = + private fun StartedNode.getContractUpgradeTransaction(state: StateAndRef) = services.validatedTransactions.getTransaction(state.ref.txhash)!! .resolveContractUpgradeTransaction(services) diff --git a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt index 52cd6e8b88..463bab114b 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt @@ -95,14 +95,14 @@ class ContractUpgradeFlowTest : WithContracts, WithFinality { and bobNode.hasDummyContractUpgradeTransaction())) } - private fun StartedNode<*>.issueCash(amount: Amount = Amount(1000, USD)) = + private fun StartedNode.issueCash(amount: Amount = Amount(1000, USD)) = services.startFlow(CashIssueFlow(amount, OpaqueBytes.of(1), notary)) .andRunNetwork() .resultFuture.getOrThrow() - private fun StartedNode<*>.getBaseStateFromVault() = getStateFromVault(ContractState::class) + private fun StartedNode.getBaseStateFromVault() = getStateFromVault(ContractState::class) - private fun StartedNode<*>.getCashStateFromVault() = getStateFromVault(CashV2.State::class) + private fun StartedNode.getCashStateFromVault() = getStateFromVault(CashV2.State::class) private fun hasIssuedAmount(expected: Amount>) = hasContractState(has(CashV2.State::amount, equalTo(expected))) @@ -172,24 +172,24 @@ class ContractUpgradeFlowTest : WithContracts, WithFinality { } //region Operations - private fun StartedNode<*>.initiateDummyContractUpgrade(tx: SignedTransaction) = + private fun StartedNode.initiateDummyContractUpgrade(tx: SignedTransaction) = initiateContractUpgrade(tx, DummyContractV2::class) - private fun StartedNode<*>.authoriseDummyContractUpgrade(tx: SignedTransaction) = + private fun StartedNode.authoriseDummyContractUpgrade(tx: SignedTransaction) = authoriseContractUpgrade(tx, DummyContractV2::class) //endregion //region Matchers - private fun StartedNode<*>.hasDummyContractUpgradeTransaction() = + private fun StartedNode.hasDummyContractUpgradeTransaction() = hasContractUpgradeTransaction() - private inline fun StartedNode<*>.hasContractUpgradeTransaction() = + private inline fun StartedNode.hasContractUpgradeTransaction() = has, ContractUpgradeLedgerTransaction>( "a contract upgrade transaction", { getContractUpgradeTransaction(it) }, isUpgrade()) - private fun StartedNode<*>.getContractUpgradeTransaction(state: StateAndRef) = + private fun StartedNode.getContractUpgradeTransaction(state: StateAndRef) = services.validatedTransactions.getTransaction(state.ref.txhash)!! .resolveContractUpgradeTransaction(services) diff --git a/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt index 6c56429518..615dc55fcb 100644 --- a/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt @@ -68,7 +68,7 @@ class FinalityFlowTests : WithFinality { willThrow()) } - private fun StartedNode<*>.signCashTransactionWith(other: Party): SignedTransaction { + private fun StartedNode.signCashTransactionWith(other: Party): SignedTransaction { val amount = 1000.POUNDS.issuedBy(alice.ref(0)) val builder = TransactionBuilder(notary) Cash().generateIssue(builder, amount, other, notary) diff --git a/core/src/test/kotlin/net/corda/core/flows/FlowTestsUtils.kt b/core/src/test/kotlin/net/corda/core/flows/FlowTestsUtils.kt index 0108e91dee..f4e34427e8 100644 --- a/core/src/test/kotlin/net/corda/core/flows/FlowTestsUtils.kt +++ b/core/src/test/kotlin/net/corda/core/flows/FlowTestsUtils.kt @@ -14,8 +14,7 @@ import co.paralleluniverse.fibers.Suspendable import net.corda.core.utilities.UntrustworthyData import net.corda.core.utilities.unwrap import net.corda.node.internal.InitiatedFlowFactory -import net.corda.node.internal.StartedNode -import net.corda.testing.node.internal.InternalMockNetwork +import net.corda.testing.node.internal.TestStartedNode import kotlin.reflect.KClass /** @@ -48,14 +47,14 @@ class NoAnswer(private val closure: () -> Unit = {}) : FlowLogic() { /** * Allows to register a flow of type [R] against an initiating flow of type [I]. */ -inline fun , reified R : FlowLogic<*>> StartedNode<*>.registerInitiatedFlow(initiatingFlowType: KClass, crossinline construct: (session: FlowSession) -> R) { +inline fun , reified R : FlowLogic<*>> TestStartedNode.registerInitiatedFlow(initiatingFlowType: KClass, crossinline construct: (session: FlowSession) -> R) { internalRegisterFlowFactory(initiatingFlowType.java, InitiatedFlowFactory.Core { session -> construct(session) }, R::class.javaObjectType, true) } /** * Allows to register a flow of type [Answer] against an initiating flow of type [I], returning a valure of type [R]. */ -inline fun , reified R : Any> StartedNode.registerAnswer(initiatingFlowType: KClass, value: R) { +inline fun , reified R : Any> TestStartedNode.registerAnswer(initiatingFlowType: KClass, value: R) { internalRegisterFlowFactory(initiatingFlowType.java, InitiatedFlowFactory.Core { session -> Answer(session, value) }, Answer::class.javaObjectType, true) } diff --git a/core/src/test/kotlin/net/corda/core/flows/ReceiveAllFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/ReceiveAllFlowTests.kt index 19e4731b92..9e1f1cb81b 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ReceiveAllFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ReceiveAllFlowTests.kt @@ -12,8 +12,6 @@ package net.corda.core.flows import co.paralleluniverse.fibers.Suspendable import com.natpryce.hamkrest.assertion.assert -import com.natpryce.hamkrest.equalTo -import com.natpryce.hamkrest.isA import net.corda.core.flows.matchers.flow.willReturn import net.corda.core.flows.mixins.WithMockNet import net.corda.core.identity.Party diff --git a/core/src/test/kotlin/net/corda/core/flows/matchers/flow/FlowMatchers.kt b/core/src/test/kotlin/net/corda/core/flows/matchers/flow/FlowMatchers.kt index afd298c7bc..7ebea9131b 100644 --- a/core/src/test/kotlin/net/corda/core/flows/matchers/flow/FlowMatchers.kt +++ b/core/src/test/kotlin/net/corda/core/flows/matchers/flow/FlowMatchers.kt @@ -3,8 +3,8 @@ package net.corda.core.flows.matchers.flow import com.natpryce.hamkrest.Matcher import com.natpryce.hamkrest.equalTo import com.natpryce.hamkrest.has -import net.corda.core.flows.matchers.willThrow import net.corda.core.flows.matchers.willReturn +import net.corda.core.flows.matchers.willThrow import net.corda.core.internal.FlowStateMachine /** diff --git a/core/src/test/kotlin/net/corda/core/flows/matchers/rpc/RpcMatchers.kt b/core/src/test/kotlin/net/corda/core/flows/matchers/rpc/RpcMatchers.kt index 69d59c5c68..dcc365d301 100644 --- a/core/src/test/kotlin/net/corda/core/flows/matchers/rpc/RpcMatchers.kt +++ b/core/src/test/kotlin/net/corda/core/flows/matchers/rpc/RpcMatchers.kt @@ -2,8 +2,8 @@ package net.corda.core.flows.matchers.rpc import com.natpryce.hamkrest.Matcher import com.natpryce.hamkrest.has -import net.corda.core.flows.matchers.willThrow import net.corda.core.flows.matchers.willReturn +import net.corda.core.flows.matchers.willThrow import net.corda.core.messaging.FlowHandle /** diff --git a/core/src/test/kotlin/net/corda/core/flows/mixins/WithContracts.kt b/core/src/test/kotlin/net/corda/core/flows/mixins/WithContracts.kt index 03da82085f..f77a11840a 100644 --- a/core/src/test/kotlin/net/corda/core/flows/mixins/WithContracts.kt +++ b/core/src/test/kotlin/net/corda/core/flows/mixins/WithContracts.kt @@ -29,33 +29,33 @@ interface WithContracts : WithMockNet { //region //region Operations - fun StartedNode<*>.signDummyContract(owner: PartyAndReference, magicNumber: Int = 0, vararg others: PartyAndReference) = + fun StartedNode.signDummyContract(owner: PartyAndReference, magicNumber: Int = 0, vararg others: PartyAndReference) = services.signDummyContract(owner, magicNumber, *others).andRunNetwork() fun ServiceHub.signDummyContract(owner: PartyAndReference, magicNumber: Int = 0, vararg others: PartyAndReference) = signInitialTransaction(createDummyContract(owner, magicNumber, *others)) - fun StartedNode<*>.collectSignatures(ptx: SignedTransaction) = + fun StartedNode.collectSignatures(ptx: SignedTransaction) = startFlowAndRunNetwork(CollectSignaturesFlow(ptx, emptySet())) - fun StartedNode<*>.addSignatureTo(ptx: SignedTransaction) = + fun StartedNode.addSignatureTo(ptx: SignedTransaction) = services.addSignature(ptx).andRunNetwork() fun > - StartedNode<*>.initiateContractUpgrade(tx: SignedTransaction, toClass: KClass) = + StartedNode.initiateContractUpgrade(tx: SignedTransaction, toClass: KClass) = initiateContractUpgrade(tx.tx.outRef(0), toClass) fun > - StartedNode<*>.initiateContractUpgrade(stateAndRef: StateAndRef, toClass: KClass) = + StartedNode.initiateContractUpgrade(stateAndRef: StateAndRef, toClass: KClass) = startFlowAndRunNetwork(ContractUpgradeFlow.Initiate(stateAndRef, toClass.java)) - fun > StartedNode<*>.authoriseContractUpgrade( + fun > StartedNode.authoriseContractUpgrade( tx: SignedTransaction, toClass: KClass) = startFlow( ContractUpgradeFlow.Authorise(tx.tx.outRef(0), toClass.java) ) - fun StartedNode<*>.deauthoriseContractUpgrade(tx: SignedTransaction) = startFlow( + fun StartedNode.deauthoriseContractUpgrade(tx: SignedTransaction) = startFlow( ContractUpgradeFlow.Deauthorise(tx.tx.outRef(0).ref) ) diff --git a/core/src/test/kotlin/net/corda/core/flows/mixins/WithFinality.kt b/core/src/test/kotlin/net/corda/core/flows/mixins/WithFinality.kt index ec0b915b1e..7d6097e878 100644 --- a/core/src/test/kotlin/net/corda/core/flows/mixins/WithFinality.kt +++ b/core/src/test/kotlin/net/corda/core/flows/mixins/WithFinality.kt @@ -16,10 +16,10 @@ import net.corda.testing.core.singleIdentity interface WithFinality : WithMockNet { //region Operations - fun StartedNode<*>.finalise(stx: SignedTransaction, vararg additionalParties: Party) = + fun StartedNode.finalise(stx: SignedTransaction, vararg additionalParties: Party) = startFlowAndRunNetwork(FinalityFlow(stx, additionalParties.toSet())) - fun StartedNode<*>.getValidatedTransaction(stx: SignedTransaction) = + fun StartedNode.getValidatedTransaction(stx: SignedTransaction) = services.validatedTransactions.getTransaction(stx.id)!! fun CordaRPCOps.finalise(stx: SignedTransaction, vararg parties: Party) = @@ -28,7 +28,7 @@ interface WithFinality : WithMockNet { //endregion //region Matchers - fun visibleTo(other: StartedNode<*>) = object : Matcher { + fun visibleTo(other: StartedNode) = object : Matcher { override val description = "has a transaction visible to ${other.info.singleIdentity()}" override fun invoke(actual: SignedTransaction) = equalTo(actual)(other.getValidatedTransaction(actual)) diff --git a/core/src/test/kotlin/net/corda/core/flows/mixins/WithMockNet.kt b/core/src/test/kotlin/net/corda/core/flows/mixins/WithMockNet.kt index c3dfbe67cd..ead51880d4 100644 --- a/core/src/test/kotlin/net/corda/core/flows/mixins/WithMockNet.kt +++ b/core/src/test/kotlin/net/corda/core/flows/mixins/WithMockNet.kt @@ -41,32 +41,32 @@ interface WithMockNet { /** * Sign an initial transaction */ - fun StartedNode<*>.signInitialTransaction(build: TransactionBuilder.() -> TransactionBuilder) = + fun StartedNode.signInitialTransaction(build: TransactionBuilder.() -> TransactionBuilder) = services.signInitialTransaction(TransactionBuilder(mockNet.defaultNotaryIdentity).build()) /** * Retrieve the sole instance of a state of a particular class from the node's vault */ - fun StartedNode<*>.getStateFromVault(stateClass: KClass) = + fun StartedNode.getStateFromVault(stateClass: KClass) = services.vaultService.queryBy(stateClass.java).states.single() /** * Start a flow */ - fun StartedNode<*>.startFlow(logic: FlowLogic): FlowStateMachine = services.startFlow(logic) + fun StartedNode.startFlow(logic: FlowLogic): FlowStateMachine = services.startFlow(logic) /** * Start a flow and run the network immediately afterwards */ - fun StartedNode<*>.startFlowAndRunNetwork(logic: FlowLogic): FlowStateMachine = + fun StartedNode.startFlowAndRunNetwork(logic: FlowLogic): FlowStateMachine = startFlow(logic).andRunNetwork() - fun StartedNode<*>.createConfidentialIdentity(party: Party) = + fun StartedNode.createConfidentialIdentity(party: Party) = services.keyManagementService.freshKeyAndCert( services.myInfo.legalIdentitiesAndCerts.single { it.name == party.name }, false) - fun StartedNode<*>.verifyAndRegister(identity: PartyAndCertificate) = + fun StartedNode.verifyAndRegister(identity: PartyAndCertificate) = services.identityService.verifyAndRegisterIdentity(identity) //endregion diff --git a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt index 0413abc452..befed707c0 100644 --- a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt +++ b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt @@ -31,6 +31,7 @@ import net.corda.testing.core.BOB_NAME import net.corda.testing.core.singleIdentity import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.internal.InternalMockNodeParameters +import net.corda.testing.node.internal.TestStartedNode import net.corda.testing.node.internal.startFlow import org.junit.After import org.junit.Before @@ -54,11 +55,11 @@ private fun Attachment.extractContent() = ByteArrayOutputStream().apply { extractFile("content", this) }.toString(UTF_8.name()) @Suppress("deprecation") -private fun StartedNode<*>.saveAttachment(content: String) = database.transaction { +private fun StartedNode.saveAttachment(content: String) = database.transaction { attachments.importAttachment(createAttachmentData(content).inputStream()) } -private fun StartedNode<*>.hackAttachment(attachmentId: SecureHash, content: String) = database.transaction { +private fun StartedNode.hackAttachment(attachmentId: SecureHash, content: String) = database.transaction { updateAttachment(attachmentId, createAttachmentData(content)) } @@ -76,8 +77,8 @@ private fun updateAttachment(attachmentId: SecureHash, data: ByteArray) { class AttachmentSerializationTest { private lateinit var mockNet: InternalMockNetwork - private lateinit var server: StartedNode - private lateinit var client: StartedNode + private lateinit var server: TestStartedNode + private lateinit var client: TestStartedNode private lateinit var serverIdentity: Party @Before diff --git a/node/src/integration-test/kotlin/net/corda/node/AuthDBTests.kt b/node/src/integration-test/kotlin/net/corda/node/AuthDBTests.kt index c8d0f2beb1..9a0fdfabe9 100644 --- a/node/src/integration-test/kotlin/net/corda/node/AuthDBTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/AuthDBTests.kt @@ -20,8 +20,8 @@ import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.startFlow import net.corda.finance.flows.CashIssueFlow import net.corda.node.internal.DataSourceFactory -import net.corda.node.internal.Node import net.corda.node.internal.StartedNode +import net.corda.node.internal.StartedNodeWithInternals import net.corda.node.services.Permissions import net.corda.node.services.config.PasswordEncryption import net.corda.testing.core.ALICE_NAME @@ -47,6 +47,7 @@ import kotlin.test.assertFailsWith */ @RunWith(Parameterized::class) class AuthDBTests : NodeBasedTest() { + companion object { @ClassRule @JvmField @@ -59,7 +60,7 @@ class AuthDBTests : NodeBasedTest() { fun encFormats() = arrayOf(PasswordEncryption.NONE, PasswordEncryption.SHIRO_1_CRYPT) } - private lateinit var node: StartedNode + private lateinit var node: StartedNodeWithInternals private lateinit var client: CordaRPCClient private lateinit var db: UsersDB diff --git a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt index 92d6494f37..1dcb036df9 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt @@ -47,7 +47,6 @@ import net.corda.testing.internal.IntegrationTest import net.corda.testing.internal.IntegrationTestSchemas import net.corda.testing.node.internal.cordappsForPackages import net.corda.testing.node.internal.InternalMockNetwork -import net.corda.testing.node.internal.InternalMockNetwork.MockNode import net.corda.testing.node.internal.InternalMockNodeParameters import net.corda.testing.node.internal.startFlow import org.hamcrest.Matchers.instanceOf @@ -75,7 +74,7 @@ class BFTNotaryServiceTests { private lateinit var mockNet: InternalMockNetwork private lateinit var notary: Party - private lateinit var node: StartedNode + private lateinit var node: StartedNode @BeforeClass @JvmStatic @@ -95,7 +94,7 @@ class BFTNotaryServiceTests { IntegrationTest.globalTearDown() //Enterprise only - remote db cleanup } - fun startBftClusterAndNode(clusterSize: Int, mockNet: InternalMockNetwork, exposeRaces: Boolean = false): Pair> { + fun startBftClusterAndNode(clusterSize: Int, mockNet: InternalMockNetwork, exposeRaces: Boolean = false): Pair { (Paths.get("config") / "currentView").deleteIfExists() // XXX: Make config object warn if this exists? val replicaIds = (0 until clusterSize) @@ -237,7 +236,7 @@ class BFTNotaryServiceTests { signatures.forEach { it.verify(txId) } } - private fun StartedNode.signInitialTransaction(notary: Party, block: TransactionBuilder.() -> Any?): SignedTransaction { + private fun StartedNode.signInitialTransaction(notary: Party, block: TransactionBuilder.() -> Any?): SignedTransaction { return services.signInitialTransaction( TransactionBuilder(notary).apply { addCommand(dummyCommand(services.myInfo.singleIdentity().owningKey)) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/BFTSMaRtTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/BFTSMaRtTests.kt index bbafa50575..0e84316052 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/BFTSMaRtTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/BFTSMaRtTests.kt @@ -16,7 +16,6 @@ import net.corda.testing.internal.IntegrationTest import net.corda.testing.internal.IntegrationTestSchemas import net.corda.testing.node.internal.cordappsForPackages import net.corda.testing.node.internal.InternalMockNetwork -import net.corda.testing.node.internal.InternalMockNetwork.MockNode import net.corda.testing.node.internal.startFlow import org.junit.After import org.junit.Before @@ -59,7 +58,7 @@ class BFTSMaRtTests : IntegrationTest() { f.getOrThrow() } - private fun StartedNode.signInitialTransaction(notary: Party, block: TransactionBuilder.() -> Any?): SignedTransaction { + private fun StartedNode.signInitialTransaction(notary: Party, block: TransactionBuilder.() -> Any?): SignedTransaction { return services.signInitialTransaction( TransactionBuilder(notary).apply { addCommand(dummyCommand(services.myInfo.singleIdentity().owningKey)) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt index bc7294b37f..c3e055b4b7 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt @@ -15,7 +15,6 @@ import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.node.NodeInfo import net.corda.core.utilities.NetworkHostAndPort -import net.corda.node.internal.Node import net.corda.node.internal.StartedNode import net.corda.testing.internal.IntegrationTestSchemas import net.corda.testing.internal.toDatabaseSchemaName @@ -126,7 +125,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { // HELPERS // Helper function to restart nodes with the same host and port. - private fun startNodesWithPort(nodesToStart: List, customRetryIntervalMs: Long? = null): List> { + private fun startNodesWithPort(nodesToStart: List, customRetryIntervalMs: Long? = null): List { return nodesToStart.map { party -> val configOverrides = (addressesMap[party.name]?.let { mapOf("p2pAddress" to it.toString()) } ?: emptyMap()) + (customRetryIntervalMs?.let { mapOf("activeMQServer.bridge.retryIntervalMs" to it.toString()) } ?: emptyMap()) diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt index eb5d18c562..cea726c681 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt @@ -24,8 +24,7 @@ import net.corda.core.messaging.CordaRPCOps import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.unwrap -import net.corda.node.internal.Node -import net.corda.node.internal.StartedNode +import net.corda.node.internal.StartedNodeWithInternals import net.corda.nodeapi.RPCApi import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.INTERNAL_PREFIX import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.NOTIFICATIONS_ADDRESS @@ -38,6 +37,7 @@ import net.corda.testing.core.singleIdentity import net.corda.testing.internal.configureTestSSL import net.corda.testing.internal.toDatabaseSchemaName import net.corda.testing.node.internal.NodeBasedTest +import net.corda.testing.node.internal.TestStartedNode import net.corda.testing.node.internal.startFlow import org.apache.activemq.artemis.api.core.ActiveMQNonExistentQueueException import org.apache.activemq.artemis.api.core.ActiveMQSecurityException @@ -61,7 +61,7 @@ abstract class MQSecurityTest : NodeBasedTest() { } val rpcUser = User("user1", "pass", permissions = emptySet()) - lateinit var alice: StartedNode + lateinit var alice: StartedNodeWithInternals lateinit var attacker: SimpleMQClient private val clients = ArrayList() diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index 97275c8a78..ceb9f154ab 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -121,24 +121,12 @@ import net.corda.core.crypto.generateKeyPair as cryptoGenerateKeyPair // In theory the NodeInfo for the node should be passed in, instead, however currently this is constructed by the // AbstractNode. It should be possible to generate the NodeInfo outside of AbstractNode, so it can be passed in. -abstract class AbstractNode(val configuration: NodeConfiguration, - val platformClock: CordaClock, - protected val versionInfo: VersionInfo, - protected val cordappLoader: CordappLoader, - protected val serverThread: AffinityExecutor.ServiceAffinityExecutor, - protected val busyNodeLatch: ReusableLatch = ReusableLatch()) : SingletonSerializeAsToken() { - - private class StartedNodeImpl( - override val internals: N, - override val info: NodeInfo, - override val rpcOps: CordaRPCOps, - override val notaryService: NotaryService?) : StartedNode { - override val smm: StateMachineManager get() = internals.smm - override val attachments: NodeAttachmentService get() = internals.attachments - override val network: MessagingService get() = internals.network - override val database: CordaPersistence get() = internals.database - override val services: StartedNodeServices = object : StartedNodeServices, ServiceHubInternal by internals.services, FlowStarter by internals.flowStarter {} - } +abstract class AbstractNode(val configuration: NodeConfiguration, + val platformClock: CordaClock, + protected val versionInfo: VersionInfo, + protected val cordappLoader: CordappLoader, + protected val serverThread: AffinityExecutor.ServiceAffinityExecutor, + private val busyNodeLatch: ReusableLatch = ReusableLatch()) : SingletonSerializeAsToken() { protected abstract val log: Logger @@ -205,7 +193,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, val services = ServiceHubInternalImpl().tokenize() @Suppress("LeakingThis") val smm = makeStateMachineManager() - private val flowStarter = FlowStarterImpl(smm, flowLogicRefFactory) + protected val flowStarter = FlowStarterImpl(smm, flowLogicRefFactory) private val schedulerService = NodeSchedulerService( platformClock, database, @@ -243,7 +231,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, /** Set to non-null once [start] has been successfully called. */ open val started get() = _started @Volatile - private var _started: StartedNode? = null + private var _started: StartedNode? = null private fun T.tokenize(): T { tokenizableServices?.add(this) ?: throw IllegalStateException("The tokenisable services list has already been finialised") @@ -305,7 +293,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, } } - open fun start(): StartedNode { + open fun start(): S { check(started == null) { "Node has already been started" } if (configuration.devMode) { @@ -401,10 +389,13 @@ abstract class AbstractNode(val configuration: NodeConfiguration, schedulerService.start() - StartedNodeImpl(this@AbstractNode, nodeInfo, rpcOps, notaryService).also { _started = it } + createStartedNode(nodeInfo, rpcOps, notaryService).also { _started = it } } } + /** Subclasses must override this to create a [StartedNode] of the desired type, using the provided machinery. */ + abstract fun createStartedNode(nodeInfo: NodeInfo, rpcOps: CordaRPCOps, notaryService: NotaryService?): S + private fun verifyCheckpointsCompatible(tokenizableServices: List) { try { CheckpointVerifier.verifyCheckpointsCompatible(checkpointStorage, cordappProvider.cordapps, versionInfo.platformVersion, services, tokenizableServices) @@ -664,7 +655,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, } } - internal fun > registerInitiatedFlow(smm: StateMachineManager, initiatedFlowClass: Class): Observable { + protected fun > registerInitiatedFlow(smm: StateMachineManager, initiatedFlowClass: Class): Observable { return registerInitiatedFlowInternal(smm, initiatedFlowClass, track = true) } @@ -700,11 +691,11 @@ abstract class AbstractNode(val configuration: NodeConfiguration, return observable } - internal fun > internalRegisterFlowFactory(smm: StateMachineManager, - initiatingFlowClass: Class>, - flowFactory: InitiatedFlowFactory, - initiatedFlowClass: Class, - track: Boolean): Observable { + protected fun > internalRegisterFlowFactory(smm: StateMachineManager, + initiatingFlowClass: Class>, + flowFactory: InitiatedFlowFactory, + initiatedFlowClass: Class, + track: Boolean): Observable { val observable = if (track) { smm.changes.filter { it is StateMachineManager.Change.Add }.map { it.logic }.ofType(initiatedFlowClass) } else { @@ -1003,7 +994,7 @@ internal fun logVendorString(database: CordaPersistence, log: Logger) { } // TODO Move this into its own file -internal class FlowStarterImpl(private val smm: StateMachineManager, private val flowLogicRefFactory: FlowLogicRefFactory) : FlowStarter { +class FlowStarterImpl(private val smm: StateMachineManager, private val flowLogicRefFactory: FlowLogicRefFactory) : FlowStarter { override fun startFlow(event: ExternalEvent.ExternalStartFlowEvent): CordaFuture> { smm.deliverExternalEvent(event) return event.future @@ -1091,4 +1082,4 @@ fun CordaPersistence.hikariStart(hikariProperties: Properties, databaseConfig: D else -> throw CouldNotCreateDataSourceException("Could not create the DataSource: ${ex.message}", ex) } } -} +} \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/internal/Node.kt b/node/src/main/kotlin/net/corda/node/internal/Node.kt index 595c92d781..a436fa273b 100644 --- a/node/src/main/kotlin/net/corda/node/internal/Node.kt +++ b/node/src/main/kotlin/net/corda/node/internal/Node.kt @@ -13,6 +13,7 @@ package net.corda.node.internal import com.codahale.metrics.JmxReporter import net.corda.client.rpc.internal.serialization.amqp.AMQPClientSerializationScheme import net.corda.core.concurrent.CordaFuture +import net.corda.core.flows.FlowLogic import net.corda.core.identity.CordaX500Name import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.Emoji @@ -20,7 +21,11 @@ import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.concurrent.thenMatch import net.corda.core.internal.div import net.corda.core.internal.errors.AddressBindingException -import net.corda.core.internal.uncheckedCast +import net.corda.core.internal.notary.NotaryService +import net.corda.node.services.api.StartedNodeServices +import net.corda.nodeapi.internal.persistence.CordaPersistence +import net.corda.node.services.statemachine.StateMachineManager +import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.RPCOps import net.corda.core.node.NetworkParameters import net.corda.core.node.NodeInfo @@ -43,6 +48,8 @@ import net.corda.node.serialization.amqp.AMQPServerSerializationScheme import net.corda.node.serialization.kryo.KRYO_CHECKPOINT_CONTEXT import net.corda.node.serialization.kryo.KryoServerSerializationScheme import net.corda.node.services.Permissions +import net.corda.node.services.api.FlowStarter +import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.SecurityConfiguration import net.corda.node.services.config.shouldInitCrashShell @@ -70,6 +77,16 @@ import java.time.Clock import java.util.concurrent.atomic.AtomicInteger import javax.management.ObjectName import kotlin.system.exitProcess +import net.corda.node.services.persistence.NodeAttachmentService +/** + * A version of [StartedNode] which exposes its [Node] internals. + * + * Although this is the type of [StartedNode] created by [Node], it is not explicitly provided + * and should not ordinarily be used (the code that _does_ use it obtains it via a cast). + */ +interface StartedNodeWithInternals : StartedNode { + val internals: Node +} /** * A Node manages a standalone server that takes part in the P2P network. It creates the services found in [ServiceHub], @@ -81,7 +98,7 @@ open class Node(configuration: NodeConfiguration, versionInfo: VersionInfo, private val initialiseSerialization: Boolean = true, cordappLoader: CordappLoader = makeCordappLoader(configuration, versionInfo) -) : AbstractNode( +) : AbstractNode( configuration, createClock(configuration), versionInfo, @@ -89,6 +106,38 @@ open class Node(configuration: NodeConfiguration, // Under normal (non-test execution) it will always be "1" AffinityExecutor.ServiceAffinityExecutor("Node thread-${sameVmNodeCounter.incrementAndGet()}", 1) ) { + + /** The actual [StartedNode] implementation created by this [AbstractNode]. */ + private class StartedNodeWithInternalsImpl( + override val internals: Node, + override val attachments: NodeAttachmentService, + override val network: MessagingService, + override val services: StartedNodeServices, + override val info: NodeInfo, + override val smm: StateMachineManager, + override val database: CordaPersistence, + override val rpcOps: CordaRPCOps, + override val notaryService: NotaryService?) : StartedNodeWithInternals { + + override fun dispose() = internals.stop() + + override fun > registerInitiatedFlow(initiatedFlowClass: Class) = + internals.registerInitiatedFlow(smm, initiatedFlowClass) + } + + override fun createStartedNode(nodeInfo: NodeInfo, rpcOps: CordaRPCOps, notaryService: NotaryService?): StartedNode = + StartedNodeWithInternalsImpl( + this, + attachments, + network, + object : StartedNodeServices, ServiceHubInternal by services, FlowStarter by flowStarter { }, + nodeInfo, + smm, + database, + rpcOps, + notaryService + ) + companion object { private val staticLog = contextLogger() var renderBasicInfoToConsole = true @@ -379,9 +428,9 @@ open class Node(configuration: NodeConfiguration, return super.generateAndSaveNodeInfo() } - override fun start(): StartedNode { + override fun start(): StartedNode { initialiseSerialization() - val started: StartedNode = uncheckedCast(super.start()) + val started: StartedNode = super.start() nodeReadyFuture.thenMatch({ serverThread.execute { // Begin exporting our own metrics via JMX. These can be monitored using any agent, e.g. Jolokia: @@ -454,4 +503,4 @@ open class Node(configuration: NodeConfiguration, log.info("Shutdown complete") } -} +} \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt index 27fa2927a0..68317c3d94 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -343,15 +343,16 @@ open class NodeStartup(val args: Array) { } val startedNode = node.start() - logLoadedCorDapps(startedNode.services.cordappProvider.cordapps) - startedNode.internals.nodeReadyFuture.thenMatch({ + logLoadedCorDapps(node.services.cordappProvider.cordapps) + Node.printBasicNodeInfo("Loaded CorDapps", startedNode.services.cordappProvider.cordapps.joinToString { it.name }) + node.nodeReadyFuture.thenMatch({ val elapsed = (System.currentTimeMillis() - startTime) / 10 / 100.0 val name = startedNode.info.legalIdentitiesAndCerts.first().name.organisation Node.printBasicNodeInfo("Node for \"$name\" started up and registered in $elapsed sec") // Don't start the shell if there's no console attached. if (conf.shouldStartLocalShell()) { - startedNode.internals.startupComplete.then { + node.startupComplete.then { try { InteractiveShell.runLocalShell({ startedNode.dispose() }) } catch (e: Throwable) { @@ -366,7 +367,7 @@ open class NodeStartup(val args: Array) { { th -> logger.error("Unexpected exception during registration", th) }) - startedNode.internals.run() + node.run() } protected open fun logStartupInfo(versionInfo: VersionInfo, cmdlineOptions: CmdLineOptions, conf: NodeConfiguration) { diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeUniqueIdProvider.kt b/node/src/main/kotlin/net/corda/node/internal/NodeUniqueIdProvider.kt index 3de44b7022..22104f96e8 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeUniqueIdProvider.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeUniqueIdProvider.kt @@ -10,13 +10,16 @@ package net.corda.node.internal +import com.google.common.annotations.VisibleForTesting + interface NodeUniqueIdProvider { val value: String } // this is stubbed because we still do not support clustered node setups. // the moment we will, this will have to be changed to return a value unique for each physical node. -internal object StubbedNodeUniqueIdProvider : NodeUniqueIdProvider { +@VisibleForTesting +object StubbedNodeUniqueIdProvider : NodeUniqueIdProvider { // TODO implement to return a value unique for each physical node when we will support clustered node setups. override val value: String = "NABOB" diff --git a/node/src/main/kotlin/net/corda/node/internal/StartedNode.kt b/node/src/main/kotlin/net/corda/node/internal/StartedNode.kt index 7307f7210a..967e0e069c 100644 --- a/node/src/main/kotlin/net/corda/node/internal/StartedNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/StartedNode.kt @@ -23,8 +23,7 @@ import net.corda.node.services.statemachine.StateMachineManager import net.corda.nodeapi.internal.persistence.CordaPersistence import rx.Observable -interface StartedNode { - val internals: N +interface StartedNode { val services: StartedNodeServices val info: NodeInfo val smm: StateMachineManager @@ -34,20 +33,12 @@ interface StartedNode { val rpcOps: CordaRPCOps val notaryService: NotaryService? - fun dispose() = internals.stop() + fun dispose() /** * Use this method to register your initiated flows in your tests. This is automatically done by the node when it * starts up for all [FlowLogic] classes it finds which are annotated with [InitiatedBy]. * @return An [Observable] of the initiated flows started by counterparties. */ - fun > registerInitiatedFlow(initiatedFlowClass: Class) = internals.registerInitiatedFlow(smm, initiatedFlowClass) - - @VisibleForTesting - fun > internalRegisterFlowFactory(initiatingFlowClass: Class>, - flowFactory: InitiatedFlowFactory, - initiatedFlowClass: Class, - track: Boolean): Observable { - return internals.internalRegisterFlowFactory(smm, initiatingFlowClass, flowFactory, initiatedFlowClass, track) - } + fun > registerInitiatedFlow(initiatedFlowClass: Class): Observable } diff --git a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt index a1728b6e7c..94559f540b 100644 --- a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt +++ b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt @@ -51,7 +51,6 @@ import net.corda.testing.core.expectEvents import net.corda.testing.core.sequence import net.corda.testing.node.internal.cordappsForPackages import net.corda.testing.node.internal.InternalMockNetwork -import net.corda.testing.node.internal.InternalMockNetwork.MockNode import net.corda.testing.node.internal.InternalMockNodeParameters import net.corda.testing.node.testActor import org.apache.commons.io.IOUtils @@ -82,7 +81,7 @@ class CordaRPCOpsImplTest { } private lateinit var mockNet: InternalMockNetwork - private lateinit var aliceNode: StartedNode + private lateinit var aliceNode: StartedNode private lateinit var alice: Party private lateinit var notary: Party private lateinit var rpc: CordaRPCOps diff --git a/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt b/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt index 70e607aaf9..e5258574ef 100644 --- a/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt +++ b/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt @@ -54,7 +54,7 @@ class NodeTest { } } - private fun AbstractNode.generateNodeInfo(): NodeInfo { + private fun Node.generateNodeInfo(): NodeInfo { assertNull(nodeInfoFile()) generateAndSaveNodeInfo() val path = nodeInfoFile()!! diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index fc7df809ab..5259049f1c 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -323,7 +323,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { // Creates a mock node with an overridden storage service that uses a RecordingMap, that lets us test the order // of gets and puts. - private fun makeNodeWithTracking(name: CordaX500Name): StartedNode { + private fun makeNodeWithTracking(name: CordaX500Name): StartedNode { // Create a node in the mock network ... return mockNet.createNode(InternalMockNodeParameters(legalName = name), nodeFactory = { args, cordappLoader -> if (cordappLoader != null) { @@ -553,8 +553,8 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { private fun runBuyerAndSeller(notary: Party, buyer: Party, - sellerNode: StartedNode, - buyerNode: StartedNode, + sellerNode: StartedNode, + buyerNode: StartedNode, assetToSell: StateAndRef): RunResult { val buyerFlows: Observable> = buyerNode.registerInitiatedFlow(BuyerAcceptor::class.java) val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine } @@ -648,10 +648,10 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { private fun insertFakeTransactions( wtxToSign: List, - node: StartedNode<*>, + node: StartedNode, identity: Party, - notaryNode: StartedNode<*>, - vararg extraSigningNodes: StartedNode<*>): Map { + notaryNode: StartedNode, + vararg extraSigningNodes: StartedNode): Map { val notaryParty = mockNet.defaultNotaryIdentity val signed = wtxToSign.map { val id = it.id diff --git a/node/src/test/kotlin/net/corda/node/modes/draining/ScheduledFlowsDrainingModeTest.kt b/node/src/test/kotlin/net/corda/node/modes/draining/ScheduledFlowsDrainingModeTest.kt index df18046284..362bdc51e0 100644 --- a/node/src/test/kotlin/net/corda/node/modes/draining/ScheduledFlowsDrainingModeTest.kt +++ b/node/src/test/kotlin/net/corda/node/modes/draining/ScheduledFlowsDrainingModeTest.kt @@ -44,8 +44,8 @@ import kotlin.test.fail class ScheduledFlowsDrainingModeTest { private lateinit var mockNet: InternalMockNetwork - private lateinit var aliceNode: StartedNode - private lateinit var bobNode: StartedNode + private lateinit var aliceNode: StartedNode + private lateinit var bobNode: StartedNode private lateinit var notary: Party private lateinit var alice: Party private lateinit var bob: Party diff --git a/node/src/test/kotlin/net/corda/node/services/FinalityHandlerTest.kt b/node/src/test/kotlin/net/corda/node/services/FinalityHandlerTest.kt index 2b04dda50e..9acde0e3ad 100644 --- a/node/src/test/kotlin/net/corda/node/services/FinalityHandlerTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/FinalityHandlerTest.kt @@ -75,7 +75,7 @@ class FinalityHandlerTest { assertThat(bob.getTransaction(finalisedTx.id)).isNull() } - private fun StartedNode<*>.assertFlowSentForObservation(runId: StateMachineRunId) { + private fun StartedNode.assertFlowSentForObservation(runId: StateMachineRunId) { val keptInForObservation = smm.flowHospital .track() .let { it.updates.startWith(it.snapshot) } @@ -86,7 +86,7 @@ class FinalityHandlerTest { assertThat(keptInForObservation.by).contains(StaffedFlowHospital.FinalityDoctor) } - private fun StartedNode<*>.getTransaction(id: SecureHash): SignedTransaction? { + private fun StartedNode.getTransaction(id: SecureHash): SignedTransaction? { return database.transaction { services.validatedTransactions.getTransaction(id) } diff --git a/node/src/test/kotlin/net/corda/node/services/TimedFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/TimedFlowTests.kt index 6383d041de..67b212eed7 100644 --- a/node/src/test/kotlin/net/corda/node/services/TimedFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/TimedFlowTests.kt @@ -46,10 +46,7 @@ import net.corda.testing.internal.GlobalDatabaseRule import net.corda.testing.internal.LogHelper import net.corda.testing.node.InMemoryMessagingNetwork import net.corda.testing.node.MockNetworkParameters -import net.corda.testing.node.internal.InternalMockNetwork -import net.corda.testing.node.internal.InternalMockNodeParameters -import net.corda.testing.node.internal.cordappsForPackages -import net.corda.testing.node.internal.startFlow +import net.corda.testing.node.internal.* import org.junit.Before import org.junit.ClassRule import org.junit.Test @@ -65,9 +62,9 @@ class TimedFlowTestRule(val clusterSize: Int) : ExternalResource() { lateinit var mockNet: InternalMockNetwork lateinit var notary: Party - lateinit var node: StartedNode + lateinit var node: TestStartedNode - private fun startClusterAndNode(mockNet: InternalMockNetwork): Pair> { + private fun startClusterAndNode(mockNet: InternalMockNetwork): Pair { val replicaIds = (0 until clusterSize) val notaryIdentity = DevIdentityGenerator.generateDistributedNotaryCompositeIdentity( replicaIds.map { mockNet.baseDirectory(mockNet.nextNodeId + it) }, @@ -187,7 +184,7 @@ class TimedFlowTests { } } - private fun StartedNode.signInitialTransaction(notary: Party, block: TransactionBuilder.() -> Any?): SignedTransaction { + private fun StartedNode.signInitialTransaction(notary: Party, block: TransactionBuilder.() -> Any?): SignedTransaction { return services.signInitialTransaction( TransactionBuilder(notary).apply { addCommand(dummyCommand(services.myInfo.singleIdentity().owningKey)) diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt index 03a28c1941..923d24df91 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt @@ -35,7 +35,6 @@ import net.corda.testing.core.dummyCommand import net.corda.testing.core.singleIdentity import net.corda.testing.node.internal.cordappsForPackages import net.corda.testing.node.internal.InternalMockNetwork -import net.corda.testing.node.internal.InternalMockNetwork.MockNode import net.corda.testing.node.internal.InternalMockNodeParameters import net.corda.testing.node.internal.startFlow import org.junit.After @@ -53,8 +52,8 @@ class ScheduledFlowTests { } private lateinit var mockNet: InternalMockNetwork - private lateinit var aliceNode: StartedNode - private lateinit var bobNode: StartedNode + private lateinit var aliceNode: StartedNode + private lateinit var bobNode: StartedNode private lateinit var notary: Party private lateinit var alice: Party private lateinit var bob: Party diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt index 7277d56a67..d785611ecc 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt @@ -46,7 +46,6 @@ import net.corda.testing.internal.LogHelper import net.corda.testing.node.InMemoryMessagingNetwork.MessageTransfer import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.internal.* -import net.corda.testing.node.internal.InternalMockNetwork.MockNode import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType @@ -67,8 +66,8 @@ class FlowFrameworkTests { } private lateinit var mockNet: InternalMockNetwork - private lateinit var aliceNode: StartedNode - private lateinit var bobNode: StartedNode + private lateinit var aliceNode: TestStartedNode + private lateinit var bobNode: TestStartedNode private lateinit var alice: Party private lateinit var bob: Party private lateinit var notaryIdentity: Party @@ -456,7 +455,7 @@ class FlowFrameworkTests { private val normalEnd = ExistingSessionMessage(SessionId(0), EndSessionMessage) // NormalSessionEnd(0) - private fun StartedNode<*>.sendSessionMessage(message: SessionMessage, destination: Party) { + private fun StartedNode.sendSessionMessage(message: SessionMessage, destination: Party) { services.networkService.apply { val address = getAddressOfParty(PartyInfo.SingleNode(destination, emptyList())) send(createMessage(FlowMessagingImpl.sessionTopic, message.serialize().bytes), address) @@ -478,9 +477,9 @@ class FlowFrameworkTripartyTests { } private lateinit var mockNet: InternalMockNetwork - private lateinit var aliceNode: StartedNode - private lateinit var bobNode: StartedNode - private lateinit var charlieNode: StartedNode + private lateinit var aliceNode: TestStartedNode + private lateinit var bobNode: TestStartedNode + private lateinit var charlieNode: TestStartedNode private lateinit var alice: Party private lateinit var bob: Party private lateinit var charlie: Party @@ -629,7 +628,7 @@ class FlowFrameworkTripartyTests { assertThat(receivedSessionMessages).containsExactly(*expected) } - private fun assertSessionTransfers(node: StartedNode, vararg expected: SessionTransfer): List { + private fun assertSessionTransfers(node: TestStartedNode, vararg expected: SessionTransfer): List { val actualForNode = receivedSessionMessages.filter { it.from == node.internals.id || it.to == node.network.myAddress } assertThat(actualForNode).containsExactly(*expected) return actualForNode @@ -646,8 +645,8 @@ class FlowFrameworkPersistenceTests { private lateinit var mockNet: InternalMockNetwork private val receivedSessionMessages = ArrayList() - private lateinit var aliceNode: StartedNode - private lateinit var bobNode: StartedNode + private lateinit var aliceNode: TestStartedNode + private lateinit var bobNode: TestStartedNode private lateinit var notaryIdentity: Party private lateinit var alice: Party private lateinit var bob: Party @@ -759,7 +758,7 @@ class FlowFrameworkPersistenceTests { //////////////////////////////////////////////////////////////////////////////////////////////////////////// //region Helpers - private inline fun > StartedNode.restartAndGetRestoredFlow(): P { + private inline fun > TestStartedNode.restartAndGetRestoredFlow(): P { val newNode = mockNet.restartNode(this) newNode.internals.acceptableLiveFiberCountOnStop = 1 mockNet.runNetwork() @@ -770,7 +769,7 @@ class FlowFrameworkPersistenceTests { assertThat(receivedSessionMessages).containsExactly(*expected) } - private fun assertSessionTransfers(node: StartedNode, vararg expected: SessionTransfer): List { + private fun assertSessionTransfers(node: TestStartedNode, vararg expected: SessionTransfer): List { val actualForNode = receivedSessionMessages.filter { it.from == node.internals.id || it.to == node.network.myAddress } assertThat(actualForNode).containsExactly(*expected) return actualForNode @@ -785,7 +784,7 @@ class FlowFrameworkPersistenceTests { private fun sessionConfirm(flowVersion: Int = 1) = ExistingSessionMessage(SessionId(0), ConfirmSessionMessage(SessionId(0), FlowInfo(flowVersion, ""))) -private inline fun > StartedNode<*>.getSingleFlow(): Pair> { +private inline fun > StartedNode.getSingleFlow(): Pair> { return smm.findStateMachines(P::class.java).single() } @@ -819,8 +818,8 @@ private fun Observable.toSessionTransfers(): Observable.sent(message: SessionMessage): Pair = Pair(internals.id, message) -private infix fun Pair.to(node: StartedNode<*>): SessionTransfer = SessionTransfer(first, second, node.network.myAddress) +private infix fun TestStartedNode.sent(message: SessionMessage): Pair = Pair(internals.id, message) +private infix fun Pair.to(node: StartedNode): SessionTransfer = SessionTransfer(first, second, node.network.myAddress) private data class SessionTransfer(val from: Int, val message: SessionMessage, val to: MessageRecipients) { val isPayloadTransfer: Boolean get() = @@ -829,7 +828,7 @@ private data class SessionTransfer(val from: Int, val message: SessionMessage, v override fun toString(): String = "$from sent $message to $to" } -private inline fun > StartedNode<*>.registerFlowFactory( +private inline fun > TestStartedNode.registerFlowFactory( initiatingFlowClass: KClass>, initiatedFlowVersion: Int = 1, noinline flowFactory: (FlowSession) -> P): CordaFuture

{ diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/IdempotentFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/IdempotentFlowTests.kt index 56a35d8409..91ca18278e 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/IdempotentFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/IdempotentFlowTests.kt @@ -27,8 +27,8 @@ import kotlin.test.assertEquals class IdempotentFlowTests { private lateinit var mockNet: InternalMockNetwork - private lateinit var nodeA: StartedNode - private lateinit var nodeB: StartedNode + private lateinit var nodeA: StartedNode + private lateinit var nodeB: StartedNode companion object { val executionCounter = AtomicInteger(0) diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/RetryFlowMockTest.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/RetryFlowMockTest.kt index fa6ad10f88..342d29fd3c 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/RetryFlowMockTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/RetryFlowMockTest.kt @@ -18,10 +18,10 @@ import net.corda.node.services.persistence.DBTransactionStorage import net.corda.nodeapi.internal.persistence.contextTransaction import net.corda.testing.node.internal.cordappsForPackages import net.corda.testing.node.internal.InternalMockNetwork -import net.corda.testing.node.internal.InternalMockNetwork.MockNode import net.corda.testing.node.internal.MessagingServiceSpy import net.corda.testing.node.internal.newContext import net.corda.testing.node.internal.setMessagingServiceSpy +import net.corda.testing.node.internal.* import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.hibernate.exception.ConstraintViolationException @@ -38,8 +38,8 @@ import kotlin.test.assertNull class RetryFlowMockTest { private lateinit var mockNet: InternalMockNetwork - private lateinit var nodeA: StartedNode - private lateinit var nodeB: StartedNode + private lateinit var nodeA: TestStartedNode + private lateinit var nodeB: TestStartedNode @Before fun start() { @@ -53,7 +53,7 @@ class RetryFlowMockTest { KeepSendingFlow.count.set(0) } - private fun StartedNode.startFlow(logic: FlowLogic): CordaFuture { + private fun StartedNode.startFlow(logic: FlowLogic): CordaFuture { return this.services.startFlow(logic, this.services.newContext()).flatMap { it.resultFuture } } diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt index 4607194afa..2eb6cc8ff3 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt @@ -37,7 +37,7 @@ import kotlin.test.assertFailsWith class NotaryServiceTests { private lateinit var mockNet: InternalMockNetwork private lateinit var notaryServices: ServiceHub - private lateinit var aliceNode: StartedNode + private lateinit var aliceNode: StartedNode private lateinit var notary: Party private lateinit var alice: Party @@ -65,7 +65,7 @@ class NotaryServiceTests { internal companion object { /** This is used by both [NotaryServiceTests] and [ValidatingNotaryServiceTests]. */ - fun notariseWithTooManyInputs(node: StartedNode, party: Party, notary: Party, network: InternalMockNetwork) { + fun notariseWithTooManyInputs(node: StartedNode, party: Party, notary: Party, network: InternalMockNetwork) { val stx = generateTransaction(node, party, notary) val future = node.services.startFlow(DummyClientFlow(stx, notary)).resultFuture @@ -73,7 +73,7 @@ class NotaryServiceTests { assertFailsWith { future.getOrThrow() } } - private fun generateTransaction(node: StartedNode, party: Party, notary: Party): SignedTransaction { + private fun generateTransaction(node: StartedNode, party: Party, notary: Party): SignedTransaction { val txHash = SecureHash.randomSHA256() val inputs = (1..10_005).map { StateRef(txHash, it) } val tx = NotaryChangeTransactionBuilder(inputs, notary, party).build() diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt index ed28b8232f..9ad99da2a3 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt @@ -37,7 +37,6 @@ import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.seconds -import net.corda.node.internal.StartedNode import net.corda.node.services.issueInvalidState import net.corda.node.services.messaging.Message import net.corda.node.services.statemachine.InitialSessionMessage @@ -53,6 +52,7 @@ import net.corda.testing.node.internal.InternalMockNodeParameters import net.corda.testing.node.internal.MessagingServiceSpy import net.corda.testing.node.internal.setMessagingServiceSpy import net.corda.testing.node.internal.startFlow +import net.corda.testing.node.internal.* import org.assertj.core.api.Assertions.assertThat import org.junit.After import org.junit.Before @@ -66,8 +66,8 @@ import kotlin.test.assertTrue class ValidatingNotaryServiceTests { private lateinit var mockNet: InternalMockNetwork - private lateinit var notaryNode: StartedNode - private lateinit var aliceNode: StartedNode + private lateinit var notaryNode: TestStartedNode + private lateinit var aliceNode: TestStartedNode private lateinit var notary: Party private lateinit var alice: Party diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/internal/DriverInternal.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/internal/DriverInternal.kt index da1ab4b34c..6cdb0e6aab 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/internal/DriverInternal.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/internal/DriverInternal.kt @@ -14,8 +14,7 @@ import net.corda.core.flows.FlowLogic import net.corda.core.messaging.CordaRPCOps import net.corda.core.node.NodeInfo import net.corda.core.utilities.NetworkHostAndPort -import net.corda.node.internal.Node -import net.corda.node.internal.StartedNode +import net.corda.node.internal.StartedNodeWithInternals import net.corda.node.services.api.StartedNodeServices import net.corda.node.services.config.NodeConfiguration import net.corda.nodeapi.internal.persistence.CordaPersistence @@ -66,7 +65,7 @@ data class InProcessImpl( override val useHTTPS: Boolean, private val nodeThread: Thread, private val onStopCallback: () -> Unit, - private val node: StartedNode + private val node: StartedNodeWithInternals ) : InProcess, NodeHandleInternal { val database: CordaPersistence get() = node.database override val services: StartedNodeServices get() = node.services diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetwork.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetwork.kt index eee0225bc3..48864a1ae2 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetwork.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetwork.kt @@ -20,7 +20,6 @@ import net.corda.core.node.NetworkParameters import net.corda.core.node.NodeInfo import net.corda.core.node.ServiceHub import net.corda.core.utilities.getOrThrow -import net.corda.node.internal.StartedNode import net.corda.node.services.config.NodeConfiguration import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.core.DUMMY_NOTARY_NAME @@ -138,9 +137,9 @@ class UnstartedMockNode private constructor(private val node: InternalMockNetwor } /** A class that represents a started mock node for testing. */ -class StartedMockNode private constructor(private val node: StartedNode) { +class StartedMockNode private constructor(private val node: TestStartedNode) { companion object { - internal fun create(node: StartedNode): StartedMockNode { + internal fun create(node: TestStartedNode): StartedMockNode { return StartedMockNode(node) } } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt index 8f064ed587..db864901db 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt @@ -32,7 +32,7 @@ import net.corda.core.utilities.* import net.corda.node.NodeRegistrationOption import net.corda.node.VersionInfo import net.corda.node.internal.Node -import net.corda.node.internal.StartedNode +import net.corda.node.internal.StartedNodeWithInternals import net.corda.node.services.Permissions import net.corda.node.services.config.* import net.corda.node.utilities.registration.HTTPNetworkRegistrationService @@ -821,7 +821,7 @@ class DriverDSLImpl( private fun startInProcessNode( executorService: ScheduledExecutorService, config: NodeConfig - ): CordaFuture, Thread>> { + ): CordaFuture> { return executorService.fork { log.info("Starting in-process Node ${config.corda.myLegalName.organisation}") if (!(ManagementFactory.getRuntimeMXBean().inputArguments.any { it.contains("quasar") })) { @@ -830,9 +830,10 @@ class DriverDSLImpl( // Write node.conf writeConfig(config.corda.baseDirectory, "node.conf", config.typesafe.toNodeOnly()) // TODO pass the version in? - val node = InProcessNode(config.corda, MOCK_VERSION_INFO).start() + val internals = InProcessNode(config.corda, MOCK_VERSION_INFO) + val node = internals.start() as StartedNodeWithInternals val nodeThread = thread(name = config.corda.myLegalName.organisation) { - node.internals.run() + internals.run() } node to nodeThread }.flatMap { nodeAndThread -> diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/InternalMockNetwork.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/InternalMockNetwork.kt index 58b98cf555..6c49ead70c 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/InternalMockNetwork.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/InternalMockNetwork.kt @@ -18,10 +18,13 @@ import net.corda.core.DoNotImplement import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash import net.corda.core.crypto.random63BitValue +import net.corda.core.flows.FlowLogic import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.* +import net.corda.core.internal.notary.NotaryService +import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.RPCOps import net.corda.core.messaging.SingleMessageRecipient @@ -34,12 +37,18 @@ import net.corda.core.utilities.* import net.corda.node.VersionInfo import net.corda.node.cordapp.CordappLoader import net.corda.node.internal.AbstractNode +import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.StartedNode import net.corda.node.internal.cordapp.JarScanningCordappLoader +import net.corda.node.services.api.FlowStarter +import net.corda.node.services.api.ServiceHubInternal +import net.corda.node.services.api.StartedNodeServices import net.corda.node.services.config.* import net.corda.node.services.keys.E2ETestKeyManagementService import net.corda.node.services.keys.KeyManagementServiceInternal import net.corda.node.services.messaging.MessagingService +import net.corda.node.services.persistence.NodeAttachmentService +import net.corda.node.services.statemachine.StateMachineManager import net.corda.node.services.transactions.BFTNonValidatingNotaryService import net.corda.node.services.transactions.BFTSMaRt import net.corda.node.services.transactions.InMemoryTransactionVerifierService @@ -47,6 +56,7 @@ import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor import net.corda.nodeapi.internal.DevIdentityGenerator import net.corda.nodeapi.internal.config.User import net.corda.nodeapi.internal.network.NetworkParametersCopier +import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.DatabaseConfig import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.driver.TestCorDapp @@ -56,6 +66,7 @@ import net.corda.testing.internal.testThreadFactory import net.corda.testing.node.* import org.apache.activemq.artemis.utils.ReusableLatch import org.apache.sshd.common.util.security.SecurityUtils +import rx.Observable import rx.Scheduler import rx.internal.schedulers.CachedThreadScheduler import java.math.BigInteger @@ -69,7 +80,7 @@ import java.util.concurrent.atomic.AtomicInteger val MOCK_VERSION_INFO = VersionInfo(1, "Mock release", "Mock revision", "Mock Vendor") -fun StartedNode.pumpReceive(block: Boolean = false): InMemoryMessagingNetwork.MessageTransfer? { +fun TestStartedNode.pumpReceive(block: Boolean = false): InMemoryMessagingNetwork.MessageTransfer? { return (network as InternalMockMessagingService).pumpReceive(block) } @@ -98,6 +109,18 @@ data class InternalMockNodeParameters( ) } +/** + * A [StartedNode] which exposes its internal [InternalMockNetwork.MockNode] for testing. + */ +interface TestStartedNode : StartedNode { + val internals: InternalMockNetwork.MockNode + + fun > internalRegisterFlowFactory(initiatingFlowClass: Class>, + flowFactory: InitiatedFlowFactory, + initiatedFlowClass: Class, + track: Boolean): Observable +} + open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParameters(), val networkSendManuallyPumped: Boolean = defaultParameters.networkSendManuallyPumped, val threadPerNode: Boolean = defaultParameters.threadPerNode, @@ -146,13 +169,13 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe * 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> + val notaryNodes: List /** * Returns the single notary node on the network. Throws if there are none or more than one. * @see notaryNodes */ - val defaultNotaryNode: StartedNode + val defaultNotaryNode: TestStartedNode get() { return when (notaryNodes.size) { 0 -> throw IllegalStateException("There are no notaries defined on the network") @@ -223,7 +246,7 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe } @VisibleForTesting - internal open fun createNotaries(): List> { + internal open fun createNotaries(): List { return notarySpecs.map { (name, validating) -> createNode(InternalMockNodeParameters(legalName = name, configOverrides = { doReturn(NotaryConfig(validating)).whenever(it).notary @@ -240,7 +263,7 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe } } - open class MockNode(args: MockNodeArgs, cordappLoader: CordappLoader = JarScanningCordappLoader.fromDirectories(args.config.cordappDirectories)) : AbstractNode( + open class MockNode(args: MockNodeArgs, cordappLoader: CordappLoader = JarScanningCordappLoader.fromDirectories(args.config.cordappDirectories)) : AbstractNode( args.config, TestClock(Clock.systemUTC()), args.version, @@ -248,6 +271,45 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe args.network.getServerThread(args.id), args.network.busyLatch ) { + + /** The actual [StartedNode] implementation created by this node */ + private class TestStartedNodeImpl( + override val internals: MockNode, + override val attachments: NodeAttachmentService, + override val network: MessagingService, + override val services: StartedNodeServices, + override val info: NodeInfo, + override val smm: StateMachineManager, + override val database: CordaPersistence, + override val rpcOps: CordaRPCOps, + override val notaryService: NotaryService?) : TestStartedNode { + + override fun > internalRegisterFlowFactory( + initiatingFlowClass: Class>, + flowFactory: InitiatedFlowFactory, + initiatedFlowClass: Class, + track: Boolean): Observable = + internals.internalRegisterFlowFactory(smm, initiatingFlowClass, flowFactory, initiatedFlowClass, track) + + override fun dispose() = internals.stop() + + override fun > registerInitiatedFlow(initiatedFlowClass: Class): Observable = + internals.registerInitiatedFlow(smm, initiatedFlowClass) + } + + override fun createStartedNode(nodeInfo: NodeInfo, rpcOps: CordaRPCOps, notaryService: NotaryService?): TestStartedNode = + TestStartedNodeImpl( + this, + attachments, + network, + object : StartedNodeServices, ServiceHubInternal by services, FlowStarter by flowStarter { }, + nodeInfo, + smm, + database, + rpcOps, + notaryService + ) + companion object { private val staticLog = contextLogger() } @@ -268,16 +330,14 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe } } - override val started: StartedNode? get() = uncheckedCast(super.started) + override val started: TestStartedNode? get() = uncheckedCast(super.started) - override fun start(): StartedNode { + override fun start(): TestStartedNode { mockNet.networkParametersCopier.install(configuration.baseDirectory) - val started: StartedNode = uncheckedCast(super.start()) - advertiseNodeToNetwork(started) - return started + return super.start().also { advertiseNodeToNetwork(it) } } - private fun advertiseNodeToNetwork(newNode: StartedNode) { + private fun advertiseNodeToNetwork(newNode: TestStartedNode) { mockNet.nodes .mapNotNull { it.started } .forEach { existingNode -> @@ -374,20 +434,20 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe return createUnstartedNode(parameters, defaultFactory) } - fun createUnstartedNode(parameters: InternalMockNodeParameters = InternalMockNodeParameters(), nodeFactory: (MockNodeArgs, CordappLoader?) -> N): N { + fun createUnstartedNode(parameters: InternalMockNodeParameters = InternalMockNodeParameters(), nodeFactory: (MockNodeArgs, CordappLoader?) -> MockNode): MockNode { return createNodeImpl(parameters, nodeFactory, false) } - fun createNode(parameters: InternalMockNodeParameters = InternalMockNodeParameters()): StartedNode { + fun createNode(parameters: InternalMockNodeParameters = InternalMockNodeParameters()): TestStartedNode { return createNode(parameters, defaultFactory) } /** Like the other [createNode] but takes a [nodeFactory] and propagates its [MockNode] subtype. */ - fun createNode(parameters: InternalMockNodeParameters = InternalMockNodeParameters(), nodeFactory: (MockNodeArgs, CordappLoader?) -> N): StartedNode { + fun createNode(parameters: InternalMockNodeParameters = InternalMockNodeParameters(), nodeFactory: (MockNodeArgs, CordappLoader?) -> MockNode): TestStartedNode { return uncheckedCast(createNodeImpl(parameters, nodeFactory, true).started)!! } - private fun createNodeImpl(parameters: InternalMockNodeParameters, nodeFactory: (MockNodeArgs, CordappLoader?) -> N, start: Boolean): N { + private fun createNodeImpl(parameters: InternalMockNodeParameters, nodeFactory: (MockNodeArgs, CordappLoader?) -> MockNode, start: Boolean): MockNode { val id = parameters.forcedID ?: nextNodeId++ val config = mockNodeConfiguration().also { doReturn(baseDirectory(id).createDirectories()).whenever(it).baseDirectory @@ -410,7 +470,7 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe return node } - fun restartNode(node: StartedNode, nodeFactory: (MockNodeArgs, CordappLoader?) -> N): StartedNode { + fun restartNode(node: TestStartedNode, nodeFactory: (MockNodeArgs, CordappLoader?) -> MockNode): TestStartedNode { node.internals.disableDBCloseOnStop() node.dispose() return createNode( @@ -419,7 +479,7 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe ) } - fun restartNode(node: StartedNode): StartedNode = restartNode(node, defaultFactory) + fun restartNode(node: TestStartedNode): TestStartedNode = restartNode(node, defaultFactory) fun baseDirectory(nodeId: Int): Path = testDirectory / "nodes/$nodeId" @@ -445,7 +505,7 @@ open class InternalMockNetwork(defaultParameters: MockNetworkParameters = MockNe } @JvmOverloads - fun createPartyNode(legalName: CordaX500Name? = null): StartedNode { + fun createPartyNode(legalName: CordaX500Name? = null): TestStartedNode { return createNode(InternalMockNodeParameters(legalName = legalName)) } @@ -486,7 +546,7 @@ open class MessagingServiceSpy(val messagingService: MessagingService) : Messagi /** * Attach a [MessagingServiceSpy] to the [InternalMockNetwork.MockNode] allowing interception and modification of messages. */ -fun StartedNode.setMessagingServiceSpy(messagingServiceSpy: MessagingServiceSpy) { +fun TestStartedNode.setMessagingServiceSpy(messagingServiceSpy: MessagingServiceSpy) { internals.setMessagingServiceSpy(messagingServiceSpy) } @@ -514,4 +574,4 @@ private fun mockNodeConfiguration(): NodeConfiguration { useMultiThreadedSMM = false )).whenever(it).enterpriseConfiguration } -} +} \ No newline at end of file diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/NodeBasedTest.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/NodeBasedTest.kt index d785f53e7a..4179665cdb 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/NodeBasedTest.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/NodeBasedTest.kt @@ -21,8 +21,7 @@ import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.loggerFor import net.corda.node.VersionInfo import net.corda.node.internal.EnterpriseNode -import net.corda.node.internal.Node -import net.corda.node.internal.StartedNode +import net.corda.node.internal.StartedNodeWithInternals import net.corda.node.services.config.* import net.corda.nodeapi.internal.config.toConfig import net.corda.nodeapi.internal.network.NetworkParametersCopier @@ -58,7 +57,7 @@ abstract class NodeBasedTest(private val cordappPackages: List = emptyLi val tempFolder = TemporaryFolder() private lateinit var defaultNetworkParameters: NetworkParametersCopier - private val startedNodes = mutableListOf>() + private val startedNodes = mutableListOf() private val nodeInfos = mutableListOf() private val portAllocation = PortAllocation.Incremental(10000) @@ -96,9 +95,9 @@ abstract class NodeBasedTest(private val cordappPackages: List = emptyLi @JvmOverloads fun initNode(legalName: CordaX500Name, - platformVersion: Int = 1, - rpcUsers: List = emptyList(), - configOverrides: Map = emptyMap()): Node { + platformVersion: Int = 1, + rpcUsers: List = emptyList(), + configOverrides: Map = emptyMap()): InProcessNode { val baseDirectory = baseDirectory(legalName).createDirectories() val p2pAddress = configOverrides["p2pAddress"] ?: portAllocation.nextHostAndPort().toString() val config = ConfigHelper.loadConfig( @@ -131,7 +130,6 @@ abstract class NodeBasedTest(private val cordappPackages: List = emptyLi } defaultNetworkParameters.install(baseDirectory) - return InProcessNode(parsedConfig, MOCK_VERSION_INFO.copy(platformVersion = platformVersion)) } @@ -139,9 +137,9 @@ abstract class NodeBasedTest(private val cordappPackages: List = emptyLi fun startNode(legalName: CordaX500Name, platformVersion: Int = 1, rpcUsers: List = emptyList(), - configOverrides: Map = emptyMap()): StartedNode { + configOverrides: Map = emptyMap()): StartedNodeWithInternals { val node = initNode(legalName,platformVersion, rpcUsers,configOverrides) - val startedNode = node.start() + val startedNode = node.start() as StartedNodeWithInternals startedNodes += startedNode ensureAllNetworkMapCachesHaveAllNodeInfos() thread(name = legalName.organisation) {