From 71c94f8a9d9595daf22e9e5f6ad152c4fc5b750d Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Mon, 19 Feb 2018 12:23:59 +0000 Subject: [PATCH] Reversing the introduction of GlobalProperties (by CORDA-961), and added NetworkParameters to ServicesForResolution instead. (#2563) Also, replaced the maxTransactionSize parameter of the driver and MockNetwork with NetworkParameters. --- .ci/api-current.txt | 24 ++--- .../corda/core/internal/GlobalProperties.kt | 14 --- .../kotlin/net/corda/core/node/ServiceHub.kt | 3 + .../core/transactions/WireTransaction.kt | 25 ++++-- docs/source/changelog.rst | 8 +- .../node/services/AttachmentLoadingTests.kt | 20 +++-- .../statemachine/LargeTransactionsTest.kt | 16 ++-- .../net/corda/node/internal/AbstractNode.kt | 35 +++++--- .../kotlin/net/corda/node/internal/Node.kt | 42 ++++++--- .../services/network/NetworkMapClientTest.kt | 2 +- .../services/network/NetworkMapUpdaterTest.kt | 4 +- .../network/NetworkParametersReaderTest.kt | 2 +- .../transactions/MaxTransactionSizeTests.kt | 5 +- .../node/services/vault/VaultQueryTests.kt | 2 +- .../node/services/vault/VaultWithCashTest.kt | 7 +- .../kotlin/net/corda/testing/driver/Driver.kt | 87 ++++++++++--------- .../net/corda/testing/node/MockNetwork.kt | 21 +++-- .../net/corda/testing/node/MockServices.kt | 32 +++++-- .../net/corda/testing/node/NodeTestUtils.kt | 3 - .../testing/node/internal/DriverDSLImpl.kt | 15 ++-- .../node/internal/InternalMockNetwork.kt | 31 +++---- .../testing/node/internal/NodeBasedTest.kt | 2 +- .../corda/testing/node/internal/RPCDriver.kt | 8 +- .../net/corda/smoketesting/NodeProcess.kt | 8 +- .../common/internal/ParametersUtilities.kt | 4 +- .../net/corda/verifier/GeneratedLedger.kt | 41 ++++++--- .../net/corda/verifier/VerifierDriver.kt | 7 +- 27 files changed, 281 insertions(+), 187 deletions(-) delete mode 100644 core/src/main/kotlin/net/corda/core/internal/GlobalProperties.kt diff --git a/.ci/api-current.txt b/.ci/api-current.txt index de26e31da6..de990eb1e3 100644 --- a/.ci/api-current.txt +++ b/.ci/api-current.txt @@ -3186,7 +3186,7 @@ public class net.corda.core.transactions.TransactionBuilder extends java.lang.Ob @org.jetbrains.annotations.NotNull public final net.corda.core.contracts.PrivacySalt getPrivacySalt() @org.jetbrains.annotations.NotNull public final Set getRequiredSigningKeys() public int hashCode() - @org.jetbrains.annotations.NotNull public final net.corda.core.transactions.LedgerTransaction toLedgerTransaction(kotlin.jvm.functions.Function1, kotlin.jvm.functions.Function1, kotlin.jvm.functions.Function1, kotlin.jvm.functions.Function1) + @kotlin.Deprecated @org.jetbrains.annotations.NotNull public final net.corda.core.transactions.LedgerTransaction toLedgerTransaction(kotlin.jvm.functions.Function1, kotlin.jvm.functions.Function1, kotlin.jvm.functions.Function1, kotlin.jvm.functions.Function1) @org.jetbrains.annotations.NotNull public final net.corda.core.transactions.LedgerTransaction toLedgerTransaction(net.corda.core.node.ServicesForResolution) @org.jetbrains.annotations.NotNull public String toString() public static final net.corda.core.transactions.WireTransaction$Companion Companion @@ -3656,12 +3656,12 @@ public final class net.corda.testing.driver.Driver extends java.lang.Object ## public final class net.corda.testing.driver.DriverParameters extends java.lang.Object public () - public (boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, Map, boolean, boolean, boolean, boolean, List, List, net.corda.testing.driver.JmxPolicy, int) + public (boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, Map, boolean, boolean, boolean, boolean, List, List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters) public final boolean component1() @org.jetbrains.annotations.NotNull public final List component10() @org.jetbrains.annotations.NotNull public final List component11() @org.jetbrains.annotations.NotNull public final net.corda.testing.driver.JmxPolicy component12() - public final int component13() + @org.jetbrains.annotations.NotNull public final net.corda.core.node.NetworkParameters component13() @org.jetbrains.annotations.NotNull public final java.nio.file.Path component2() @org.jetbrains.annotations.NotNull public final net.corda.testing.driver.PortAllocation component3() @org.jetbrains.annotations.NotNull public final net.corda.testing.driver.PortAllocation component4() @@ -3670,14 +3670,14 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O public final boolean component7() public final boolean component8() public final boolean component9() - @org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters copy(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, Map, boolean, boolean, boolean, boolean, List, List, net.corda.testing.driver.JmxPolicy, int) + @org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters copy(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, Map, boolean, boolean, boolean, boolean, List, List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters) public boolean equals(Object) @org.jetbrains.annotations.NotNull public final net.corda.testing.driver.PortAllocation getDebugPortAllocation() @org.jetbrains.annotations.NotNull public final java.nio.file.Path getDriverDirectory() @org.jetbrains.annotations.NotNull public final List getExtraCordappPackagesToScan() public final boolean getInitialiseSerialization() @org.jetbrains.annotations.NotNull public final net.corda.testing.driver.JmxPolicy getJmxPolicy() - public final int getMaxTransactionSize() + @org.jetbrains.annotations.NotNull public final net.corda.core.node.NetworkParameters getNetworkParameters() @org.jetbrains.annotations.NotNull public final List getNotarySpecs() @org.jetbrains.annotations.NotNull public final net.corda.testing.driver.PortAllocation getPortAllocation() public final boolean getStartNodesInProcess() @@ -3911,7 +3911,7 @@ public final class net.corda.testing.node.MockKeyManagementService extends net.c public class net.corda.testing.node.MockNetwork extends java.lang.Object public (List) public (List, net.corda.testing.node.MockNetworkParameters) - public (List, net.corda.testing.node.MockNetworkParameters, boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, boolean, List, int) + public (List, net.corda.testing.node.MockNetworkParameters, boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, boolean, List, net.corda.core.node.NetworkParameters) @org.jetbrains.annotations.NotNull public final java.nio.file.Path baseDirectory(int) @org.jetbrains.annotations.NotNull public final net.corda.testing.node.StartedMockNode createNode() @org.jetbrains.annotations.NotNull public final net.corda.testing.node.StartedMockNode createNode(net.corda.core.identity.CordaX500Name) @@ -3933,7 +3933,7 @@ public class net.corda.testing.node.MockNetwork extends java.lang.Object @org.jetbrains.annotations.NotNull public final net.corda.testing.node.StartedMockNode getDefaultNotaryNode() @org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters getDefaultParameters() public final boolean getInitialiseSerialization() - public final int getMaxTransactionSize() + @org.jetbrains.annotations.NotNull public final net.corda.core.node.NetworkParameters getNetworkParameters() public final boolean getNetworkSendManuallyPumped() public final int getNextNodeId() @org.jetbrains.annotations.NotNull public final List getNotaryNodes() @@ -3960,24 +3960,24 @@ public final class net.corda.testing.node.MockNetworkNotarySpec extends java.lan ## public final class net.corda.testing.node.MockNetworkParameters extends java.lang.Object public () - public (boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, boolean, List, int) + public (boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, boolean, List, net.corda.core.node.NetworkParameters) public final boolean component1() public final boolean component2() @org.jetbrains.annotations.NotNull public final net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy component3() public final boolean component4() @org.jetbrains.annotations.NotNull public final List component5() - public final int component6() - @org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters copy(boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, boolean, List, int) + @org.jetbrains.annotations.NotNull public final net.corda.core.node.NetworkParameters component6() + @org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters copy(boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, boolean, List, net.corda.core.node.NetworkParameters) public boolean equals(Object) public final boolean getInitialiseSerialization() - public final int getMaxTransactionSize() + @org.jetbrains.annotations.NotNull public final net.corda.core.node.NetworkParameters getNetworkParameters() public final boolean getNetworkSendManuallyPumped() @org.jetbrains.annotations.NotNull public final List getNotarySpecs() @org.jetbrains.annotations.NotNull public final net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy getServicePeerAllocationStrategy() public final boolean getThreadPerNode() public int hashCode() @org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setInitialiseSerialization(boolean) - @org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setMaxTransactionSize(int) + @org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setNetworkParameters(net.corda.core.node.NetworkParameters) @org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setNetworkSendManuallyPumped(boolean) @org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setNotarySpecs(List) @org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setServicePeerAllocationStrategy(net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy) diff --git a/core/src/main/kotlin/net/corda/core/internal/GlobalProperties.kt b/core/src/main/kotlin/net/corda/core/internal/GlobalProperties.kt deleted file mode 100644 index bedac0269a..0000000000 --- a/core/src/main/kotlin/net/corda/core/internal/GlobalProperties.kt +++ /dev/null @@ -1,14 +0,0 @@ -package net.corda.core.internal - -import net.corda.core.node.NetworkParameters - -// TODO: This will cause problems when we run tests in parallel, make each node have its own properties. -object GlobalProperties { - private var _networkParameters: NetworkParameters? = null - - var networkParameters: NetworkParameters - get() = checkNotNull(_networkParameters) { "Property 'networkParameters' has not been initialised." } - set(value) { - _networkParameters = value - } -} \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt b/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt index 2c31eb96f1..0d2f36ff43 100644 --- a/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt +++ b/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt @@ -61,6 +61,9 @@ interface ServicesForResolution : StateLoader { /** Provides access to anything relating to cordapps including contract attachment resolution and app context */ val cordappProvider: CordappProvider + + /** Returns the network parameters the node is operating under. */ + val networkParameters: NetworkParameters } /** diff --git a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt index d973152262..8e397b9051 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt @@ -5,7 +5,6 @@ import net.corda.core.contracts.ComponentGroupEnum.* import net.corda.core.crypto.* import net.corda.core.identity.Party import net.corda.core.internal.Emoji -import net.corda.core.internal.GlobalProperties import net.corda.core.node.ServicesForResolution import net.corda.core.node.services.AttachmentId import net.corda.core.serialization.CordaSerializable @@ -85,11 +84,12 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr */ @Throws(AttachmentResolutionException::class, TransactionResolutionException::class) fun toLedgerTransaction(services: ServicesForResolution): LedgerTransaction { - return toLedgerTransaction( + return toLedgerTransactionInternal( resolveIdentity = { services.identityService.partyFromKey(it) }, resolveAttachment = { services.attachments.openAttachment(it) }, resolveStateRef = { services.loadState(it) }, - resolveContractAttachment = { services.cordappProvider.getContractAttachmentID(it.contract) } + resolveContractAttachment = { services.cordappProvider.getContractAttachmentID(it.contract) }, + maxTransactionSize = services.networkParameters.maxTransactionSize ) } @@ -100,12 +100,23 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr * @throws AttachmentResolutionException if a required attachment was not found using [resolveAttachment]. * @throws TransactionResolutionException if an input was not found not using [resolveStateRef]. */ + @Deprecated("Use toLedgerTransaction(ServicesForTransaction) instead") @Throws(AttachmentResolutionException::class, TransactionResolutionException::class) fun toLedgerTransaction( resolveIdentity: (PublicKey) -> Party?, resolveAttachment: (SecureHash) -> Attachment?, resolveStateRef: (StateRef) -> TransactionState<*>?, resolveContractAttachment: (TransactionState) -> AttachmentId? + ): LedgerTransaction { + return toLedgerTransactionInternal(resolveIdentity, resolveAttachment, resolveStateRef, resolveContractAttachment, 10485760) + } + + private fun toLedgerTransactionInternal( + resolveIdentity: (PublicKey) -> Party?, + resolveAttachment: (SecureHash) -> Attachment?, + resolveStateRef: (StateRef) -> TransactionState<*>?, + resolveContractAttachment: (TransactionState) -> AttachmentId?, + maxTransactionSize: Int ): LedgerTransaction { // Look up public keys to authenticated identities. This is just a stub placeholder and will all change in future. val authenticatedArgs = commands.map { @@ -120,15 +131,15 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr // Order of attachments is important since contracts may refer to indexes so only append automatic attachments val attachments = (attachments.map { resolveAttachment(it) ?: throw AttachmentResolutionException(it) } + contractAttachments).distinct() val ltx = LedgerTransaction(resolvedInputs, outputs, authenticatedArgs, attachments, id, notary, timeWindow, privacySalt) - checkTransactionSize(ltx) + checkTransactionSize(ltx, maxTransactionSize) return ltx } - private fun checkTransactionSize(ltx: LedgerTransaction) { - var remainingTransactionSize = GlobalProperties.networkParameters.maxTransactionSize + private fun checkTransactionSize(ltx: LedgerTransaction, maxTransactionSize: Int) { + var remainingTransactionSize = maxTransactionSize fun minus(size: Int) { - require(remainingTransactionSize > size) { "Transaction exceeded network's maximum transaction size limit : ${GlobalProperties.networkParameters.maxTransactionSize} bytes." } + require(remainingTransactionSize > size) { "Transaction exceeded network's maximum transaction size limit : $maxTransactionSize bytes." } remainingTransactionSize -= size } diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 51b08d6924..ffe65a63bb 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -76,7 +76,10 @@ UNRELEASED :doc:`corda-configuration-file` for more details. * Introducing the concept of network parameters which are a set of constants which all nodes on a network must agree on - to correctly interop. + to correctly interop. These can be retrieved from ``ServiceHub.networkParameters``. + + * One of these parameters, ``maxTransactionSize``, limits the size of a transaction, including its attachments, so that + all nodes have sufficient memory to validate transactions. * The set of valid notaries has been moved to the network parameters. Notaries are no longer identified by the CN in their X500 name. @@ -89,9 +92,6 @@ UNRELEASED * Moved ``NodeInfoSchema`` to internal package as the node info's database schema is not part of the public API. This was needed to allow changes to the schema. - * Introduced max transaction size limit on transactions. The max transaction size parameter is set by the compatibility zone - operator. The parameter is distributed to Corda nodes by network map service as part of the ``NetworkParameters``. - * Support for external user credentials data source and password encryption [CORDA-827]. * Exporting additional JMX metrics (artemis, hibernate statistics) and loading Jolokia agent at JVM startup when using diff --git a/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt index 01582516b5..b419fdefcc 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt @@ -4,6 +4,9 @@ import com.nhaarman.mockito_kotlin.doReturn import com.nhaarman.mockito_kotlin.whenever import net.corda.core.contracts.Contract import net.corda.core.contracts.PartyAndReference +import net.corda.core.contracts.StateRef +import net.corda.core.contracts.TransactionState +import net.corda.core.cordapp.CordappProvider import net.corda.core.flows.FlowLogic import net.corda.core.flows.UnexpectedFlowEndException import net.corda.core.identity.CordaX500Name @@ -12,7 +15,9 @@ import net.corda.core.internal.concurrent.transpose import net.corda.core.internal.createDirectories import net.corda.core.internal.div import net.corda.core.internal.toLedgerTransaction +import net.corda.core.node.NetworkParameters import net.corda.core.node.ServicesForResolution +import net.corda.core.node.services.AttachmentStorage import net.corda.core.node.services.IdentityService import net.corda.core.serialization.SerializationFactory import net.corda.core.transactions.TransactionBuilder @@ -20,6 +25,7 @@ import net.corda.core.utilities.contextLogger import net.corda.core.utilities.getOrThrow import net.corda.node.internal.cordapp.CordappLoader import net.corda.node.internal.cordapp.CordappProviderImpl +import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.core.DUMMY_BANK_A_NAME import net.corda.testing.core.DUMMY_NOTARY_NAME import net.corda.testing.core.SerializationEnvironmentRule @@ -79,12 +85,14 @@ class AttachmentLoadingTests { } } - private val services = rigorousMock().also { - doReturn(attachments).whenever(it).attachments - doReturn(provider).whenever(it).cordappProvider - doReturn(rigorousMock().also { - doReturn(null).whenever(it).partyFromKey(DUMMY_BANK_A.owningKey) - }).whenever(it).identityService + private val services = object : ServicesForResolution { + override fun loadState(stateRef: StateRef): TransactionState<*> = throw NotImplementedError() + override val identityService = rigorousMock().apply { + doReturn(null).whenever(this).partyFromKey(DUMMY_BANK_A.owningKey) + } + override val attachments: AttachmentStorage get() = this@AttachmentLoadingTests.attachments + override val cordappProvider: CordappProvider get() = this@AttachmentLoadingTests.provider + override val networkParameters: NetworkParameters = testNetworkParameters() } @Test diff --git a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt index cd5f572d50..aa007be6d7 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt @@ -9,6 +9,8 @@ import net.corda.core.internal.concurrent.transpose import net.corda.core.messaging.startFlow import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow +import net.corda.node.services.config.MB +import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyState import net.corda.testing.core.* @@ -68,11 +70,15 @@ class LargeTransactionsTest { fun checkCanSendLargeTransactions() { // These 4 attachments yield a transaction that's got >10mb attached, so it'd push us over the Artemis // max message size. - val bigFile1 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 0) - val bigFile2 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 1) - val bigFile3 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 2) - val bigFile4 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 3) - driver(DriverParameters(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.testing.contracts"), portAllocation = PortAllocation.RandomFree)) { + val bigFile1 = InputStreamAndHash.createInMemoryTestZip(3.MB.toInt(), 0) + val bigFile2 = InputStreamAndHash.createInMemoryTestZip(3.MB.toInt(), 1) + val bigFile3 = InputStreamAndHash.createInMemoryTestZip(3.MB.toInt(), 2) + val bigFile4 = InputStreamAndHash.createInMemoryTestZip(3.MB.toInt(), 3) + driver(DriverParameters( + startNodesInProcess = true, + extraCordappPackagesToScan = listOf("net.corda.testing.contracts"), + networkParameters = testNetworkParameters(maxTransactionSize = 13.MB.toInt()), + portAllocation = PortAllocation.RandomFree)) { val rpcUser = User("admin", "admin", setOf("ALL")) val (alice, _) = listOf(ALICE_NAME, BOB_NAME).map { startNode(providedName = it, rpcUsers = listOf(rpcUser)) }.transpose().getOrThrow() CordaRPCClient(alice.rpcAddress).use(rpcUser.username, rpcUser.password) { 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 daf5873530..fbf823fba2 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -14,7 +14,6 @@ import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.FlowStateMachine -import net.corda.core.internal.GlobalProperties import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.concurrent.map import net.corda.core.internal.concurrent.openFuture @@ -59,8 +58,8 @@ import net.corda.node.services.vault.NodeVaultService import net.corda.node.services.vault.VaultSoftLockManager import net.corda.node.shell.InteractiveShell import net.corda.node.utilities.AffinityExecutor -import net.corda.node.utilities.NodeBuildProperties import net.corda.node.utilities.JVMAgentRegistry +import net.corda.node.utilities.NodeBuildProperties import net.corda.nodeapi.internal.DevIdentityGenerator import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.persistence.CordaPersistence @@ -200,18 +199,27 @@ abstract class AbstractNode(val configuration: NodeConfiguration, val (identity, identityKeyPair) = obtainIdentity(notaryConfig = null) val identityService = makeIdentityService(identity.certificate) networkMapClient = configuration.compatibilityZoneURL?.let { NetworkMapClient(it, identityService.trustRoot) } - GlobalProperties.networkParameters = NetworkParametersReader(identityService.trustRoot, networkMapClient, configuration.baseDirectory).networkParameters - check(GlobalProperties.networkParameters.minimumPlatformVersion <= versionInfo.platformVersion) { + val networkParameters = NetworkParametersReader(identityService.trustRoot, networkMapClient, configuration.baseDirectory).networkParameters + check(networkParameters.minimumPlatformVersion <= versionInfo.platformVersion) { "Node's platform version is lower than network's required minimumPlatformVersion" } // Do all of this in a database transaction so anything that might need a connection has one. val (startedImpl, schedulerService) = initialiseDatabasePersistence(schemaService, identityService) { database -> - val networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database, GlobalProperties.networkParameters.notaries).start(), identityService) + val networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database, networkParameters.notaries).start(), identityService) val (keyPairs, nodeInfo) = initNodeInfo(networkMapCache, identity, identityKeyPair) identityService.loadIdentities(nodeInfo.legalIdentitiesAndCerts) val transactionStorage = makeTransactionStorage(database, configuration.transactionCacheSizeBytes) val nodeProperties = NodePropertiesPersistentStore(StubbedNodeUniqueIdProvider::value, database) - val nodeServices = makeServices(keyPairs, schemaService, transactionStorage, database, nodeInfo, identityService, networkMapCache, nodeProperties) + val nodeServices = makeServices( + keyPairs, + schemaService, + transactionStorage, + database, + nodeInfo, + identityService, + networkMapCache, + nodeProperties, + networkParameters) val notaryService = makeNotaryService(nodeServices, database) val smm = makeStateMachineManager(database) val flowLogicRefFactory = FlowLogicRefFactoryImpl(cordappLoader.appClassLoader) @@ -248,7 +256,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, networkMapUpdater = NetworkMapUpdater(services.networkMapCache, NodeInfoWatcher(configuration.baseDirectory, getRxIoScheduler(), Duration.ofMillis(configuration.additionalNodeInfoPollingFrequencyMsec)), networkMapClient, - GlobalProperties.networkParameters.serialize().hash, + networkParameters.serialize().hash, configuration.baseDirectory) runOnStop += networkMapUpdater::close @@ -543,7 +551,8 @@ abstract class AbstractNode(val configuration: NodeConfiguration, nodeInfo: NodeInfo, identityService: IdentityServiceInternal, networkMapCache: NetworkMapCacheInternal, - nodeProperties: NodePropertiesStore): MutableList { + nodeProperties: NodePropertiesStore, + networkParameters: NetworkParameters): MutableList { checkpointStorage = DBCheckpointStorage() val metrics = MetricRegistry() attachments = NodeAttachmentService(metrics, configuration.attachmentContentCacheSizeBytes, configuration.attachmentCacheBound) @@ -559,8 +568,9 @@ abstract class AbstractNode(val configuration: NodeConfiguration, database, nodeInfo, networkMapCache, - nodeProperties) - network = makeMessagingService(database, nodeInfo, nodeProperties) + nodeProperties, + networkParameters) + network = makeMessagingService(database, nodeInfo, nodeProperties, networkParameters) val tokenizableServices = mutableListOf(attachments, network, services.vaultService, services.keyManagementService, services.identityService, platformClock, services.auditService, services.monitoringService, services.networkMapCache, services.schemaService, @@ -695,7 +705,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, _started = null } - protected abstract fun makeMessagingService(database: CordaPersistence, info: NodeInfo, nodeProperties: NodePropertiesStore): MessagingService + protected abstract fun makeMessagingService(database: CordaPersistence, info: NodeInfo, nodeProperties: NodePropertiesStore, networkParameters: NetworkParameters): MessagingService protected abstract fun startMessagingService(rpcOps: RPCOps) private fun obtainIdentity(notaryConfig: NotaryConfig?): Pair { @@ -783,7 +793,8 @@ abstract class AbstractNode(val configuration: NodeConfiguration, override val database: CordaPersistence, override val myInfo: NodeInfo, override val networkMapCache: NetworkMapCacheInternal, - override val nodeProperties: NodePropertiesStore + override val nodeProperties: NodePropertiesStore, + override val networkParameters: NetworkParameters ) : SingletonSerializeAsToken(), ServiceHubInternal, StateLoader by validatedTransactions { override val rpcFlows = ArrayList>>() override val stateMachineRecordedTransactionMapping = DBTransactionMappingStorage() 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 395577f49e..d15d749d05 100644 --- a/node/src/main/kotlin/net/corda/node/internal/Node.kt +++ b/node/src/main/kotlin/net/corda/node/internal/Node.kt @@ -2,12 +2,12 @@ package net.corda.node.internal import com.codahale.metrics.JmxReporter import net.corda.core.concurrent.CordaFuture -import net.corda.core.internal.GlobalProperties.networkParameters 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.uncheckedCast import net.corda.core.messaging.RPCOps +import net.corda.core.node.NetworkParameters import net.corda.core.node.NodeInfo import net.corda.core.node.ServiceHub import net.corda.core.node.services.IdentityService @@ -147,7 +147,10 @@ open class Node(configuration: NodeConfiguration, private var shutdownHook: ShutdownHook? = null - override fun makeMessagingService(database: CordaPersistence, info: NodeInfo, nodeProperties: NodePropertiesStore): MessagingService { + override fun makeMessagingService(database: CordaPersistence, + info: NodeInfo, + nodeProperties: NodePropertiesStore, + networkParameters: NetworkParameters): MessagingService { // Construct security manager reading users data either from the 'security' config section // if present or from rpcUsers list if the former is missing from config. val securityManagerConfig = configuration.security?.authService ?: @@ -155,8 +158,12 @@ open class Node(configuration: NodeConfiguration, securityManager = RPCSecurityManagerImpl(securityManagerConfig) - val serverAddress = configuration.messagingServerAddress ?: makeLocalMessageBroker() - val rpcServerAddresses = if (configuration.rpcOptions.standAloneBroker) BrokerAddresses(configuration.rpcOptions.address!!, configuration.rpcOptions.adminAddress) else startLocalRpcBroker() + val serverAddress = configuration.messagingServerAddress ?: makeLocalMessageBroker(networkParameters) + val rpcServerAddresses = if (configuration.rpcOptions.standAloneBroker) { + BrokerAddresses(configuration.rpcOptions.address!!, configuration.rpcOptions.adminAddress) + } else { + startLocalRpcBroker(networkParameters) + } val advertisedAddress = info.addresses[0] bridgeControlListener = BridgeControlListener(configuration, serverAddress, networkParameters.maxMessageSize) @@ -185,16 +192,31 @@ open class Node(configuration: NodeConfiguration, drainingModeWasChangedEvents = nodeProperties.flowsDrainingMode.values) } - private fun startLocalRpcBroker(): BrokerAddresses? { + private fun startLocalRpcBroker(networkParameters: NetworkParameters): BrokerAddresses? { with(configuration) { return rpcOptions.address?.let { require(rpcOptions.address != null) { "RPC address needs to be specified for local RPC broker." } val rpcBrokerDirectory: Path = baseDirectory / "brokers" / "rpc" with(rpcOptions) { rpcBroker = if (useSsl) { - ArtemisRpcBroker.withSsl(this.address!!, sslConfig, securityManager, certificateChainCheckPolicies, networkParameters.maxMessageSize, jmxMonitoringHttpPort != null, rpcBrokerDirectory) + ArtemisRpcBroker.withSsl( + this.address!!, + sslConfig, + securityManager, + certificateChainCheckPolicies, + networkParameters.maxMessageSize, + jmxMonitoringHttpPort != null, + rpcBrokerDirectory) } else { - ArtemisRpcBroker.withoutSsl(this.address!!, adminAddress!!, sslConfig, securityManager, certificateChainCheckPolicies, networkParameters.maxMessageSize, jmxMonitoringHttpPort != null, rpcBrokerDirectory) + ArtemisRpcBroker.withoutSsl( + this.address!!, + adminAddress!!, + sslConfig, + securityManager, + certificateChainCheckPolicies, + networkParameters.maxMessageSize, + jmxMonitoringHttpPort != null, + rpcBrokerDirectory) } } return rpcBroker!!.addresses @@ -202,16 +224,14 @@ open class Node(configuration: NodeConfiguration, } } - private fun makeLocalMessageBroker(): NetworkHostAndPort { + private fun makeLocalMessageBroker(networkParameters: NetworkParameters): NetworkHostAndPort { with(configuration) { messageBroker = ArtemisMessagingServer(this, p2pAddress.port, networkParameters.maxMessageSize) return NetworkHostAndPort("localhost", p2pAddress.port) } } - override fun myAddresses(): List { - return listOf(getAdvertisedAddress()) - } + override fun myAddresses(): List = listOf(getAdvertisedAddress()) private fun getAdvertisedAddress(): NetworkHostAndPort { return with(configuration) { diff --git a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapClientTest.kt b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapClientTest.kt index 283ae2c71a..6582196e27 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapClientTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapClientTest.kt @@ -98,7 +98,7 @@ class NetworkMapClientTest { @Test fun `handle parameters update`() { - val nextParameters = testNetworkParameters(emptyList(), epoch = 2) + val nextParameters = testNetworkParameters(epoch = 2) val originalNetworkParameterHash = server.networkParameters.serialize().hash val nextNetworkParameterHash = nextParameters.serialize().hash val description = "Test parameters" diff --git a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt index a00bf44a35..fd0214955d 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt @@ -201,7 +201,7 @@ class NetworkMapUpdaterTest { val snapshot = paramsFeed.snapshot val updates = paramsFeed.updates.bufferUntilSubscribed() assertEquals(null, snapshot) - val newParameters = testNetworkParameters(emptyList(), epoch = 2) + val newParameters = testNetworkParameters(epoch = 2) val updateDeadline = Instant.now().plus(1, ChronoUnit.DAYS) scheduleParametersUpdate(newParameters, "Test update", updateDeadline) updater.subscribeToNetworkMap() @@ -219,7 +219,7 @@ class NetworkMapUpdaterTest { @Test fun `ack network parameters update`() { - val newParameters = testNetworkParameters(emptyList(), epoch = 314) + val newParameters = testNetworkParameters(epoch = 314) scheduleParametersUpdate(newParameters, "Test update", Instant.MIN) updater.subscribeToNetworkMap() // TODO: Remove sleep in unit test. diff --git a/node/src/test/kotlin/net/corda/node/services/network/NetworkParametersReaderTest.kt b/node/src/test/kotlin/net/corda/node/services/network/NetworkParametersReaderTest.kt index abd8d33fd1..86fba98581 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/NetworkParametersReaderTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/NetworkParametersReaderTest.kt @@ -50,7 +50,7 @@ class NetworkParametersReaderTest { fun `read correct set of parameters from file`() { val fs = Jimfs.newFileSystem(Configuration.unix()) val baseDirectory = fs.getPath("/node").createDirectories() - val oldParameters = testNetworkParameters(emptyList(), epoch = 1) + val oldParameters = testNetworkParameters(epoch = 1) NetworkParametersCopier(oldParameters).install(baseDirectory) NetworkParametersCopier(server.networkParameters, update = true).install(baseDirectory) // Parameters update file. val parameters = NetworkParametersReader(DEV_ROOT_CA.certificate, networkMapClient, baseDirectory).networkParameters diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/MaxTransactionSizeTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/MaxTransactionSizeTests.kt index 7b6a077b8d..1b041bcde8 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/MaxTransactionSizeTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/MaxTransactionSizeTests.kt @@ -8,6 +8,7 @@ import net.corda.core.internal.InputStreamAndHash import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow import net.corda.node.services.api.StartedNodeServices +import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyState import net.corda.testing.core.ALICE_NAME @@ -34,7 +35,9 @@ class MaxTransactionSizeTests { @Before fun setup() { - mockNet = MockNetwork(listOf("net.corda.testing.contracts", "net.corda.node.services.transactions"), maxTransactionSize = 3_000_000) + mockNet = MockNetwork( + listOf("net.corda.testing.contracts", "net.corda.node.services.transactions"), + networkParameters = testNetworkParameters(maxTransactionSize = 3_000_000)) val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME)) val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME)) notaryServices = mockNet.defaultNotaryNode.services diff --git a/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt b/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt index c75bf3f447..04e0b34c37 100644 --- a/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt @@ -110,7 +110,7 @@ class VaultQueryTests { cordappPackages, makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, dummyCashIssuer.identity, dummyNotary.identity), megaCorp, - DUMMY_NOTARY_KEY) + moreKeys = DUMMY_NOTARY_KEY) database = databaseAndServices.first services = databaseAndServices.second vaultFiller = VaultFiller(services, dummyNotary) diff --git a/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt b/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt index 1dcb7cb984..e7e3a50ea2 100644 --- a/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt @@ -1,6 +1,9 @@ package net.corda.node.services.vault -import net.corda.core.contracts.* +import net.corda.core.contracts.ContractState +import net.corda.core.contracts.InsufficientBalanceException +import net.corda.core.contracts.LinearState +import net.corda.core.contracts.UniqueIdentifier import net.corda.core.crypto.generateKeyPair import net.corda.core.identity.AnonymousParty import net.corda.core.identity.CordaX500Name @@ -74,7 +77,7 @@ class VaultWithCashTest { cordappPackages, makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, dummyCashIssuer.identity, dummyNotary.identity), TestIdentity(MEGA_CORP.name, servicesKey), - dummyNotary.keyPair) + moreKeys = dummyNotary.keyPair) database = databaseAndServices.first services = databaseAndServices.second vaultFiller = VaultFiller(services, dummyNotary) diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt index bf06b7cb08..03ce962d2a 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt @@ -8,12 +8,13 @@ import net.corda.core.flows.FlowLogic import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.messaging.CordaRPCOps +import net.corda.core.node.NetworkParameters import net.corda.core.node.NodeInfo import net.corda.core.utilities.NetworkHostAndPort import net.corda.node.internal.Node import net.corda.node.services.api.StartedNodeServices import net.corda.node.services.config.VerifierType -import net.corda.nodeapi.internal.persistence.CordaPersistence +import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.core.DUMMY_NOTARY_NAME import net.corda.testing.node.NotarySpec import net.corda.testing.node.User @@ -25,7 +26,6 @@ import java.net.InetSocketAddress import java.net.ServerSocket import java.nio.file.Path import java.nio.file.Paths -import java.sql.Connection import java.util.concurrent.atomic.AtomicInteger /** @@ -109,6 +109,12 @@ data class NodeParameters( fun setMaximumHeapSize(maximumHeapSize: String): NodeParameters = copy(maximumHeapSize = maximumHeapSize) } +/** + * @property startJmxHttpServer Indicates whether the spawned nodes should start with a Jolokia JMX agent to enable remote + * JMX monitoring using HTTP/JSON + * @property jmxHttpServerPortAllocation The port allocation strategy to use for remote Jolokia/JMX monitoring over HTTP. + * Defaults to incremental. + */ data class JmxPolicy(val startJmxHttpServer: Boolean = false, val jmxHttpServerPortAllocation: PortAllocation? = if (startJmxHttpServer) PortAllocation.Incremental(7005) else null) @@ -128,30 +134,10 @@ data class JmxPolicy(val startJmxHttpServer: Boolean = false, * * @param defaultParameters The default parameters for the driver. Allows the driver to be configured in builder style * when called from Java code. - * @param isDebug Indicates whether the spawned nodes should start in jdwt debug mode and have debug level logging. - * @param driverDirectory The base directory node directories go into, defaults to "build//". The node - * directories themselves are "//", where legalName defaults to "-" - * and may be specified in [DriverDSL.startNode]. - * @param portAllocation The port allocation strategy to use for the messaging and the web server addresses. Defaults to incremental. - * @param debugPortAllocation The port allocation strategy to use for jvm debugging. Defaults to incremental. - * @param systemProperties A Map of extra system properties which will be given to each new node. Defaults to empty. - * @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 - * not. Note that this may be overridden in [DriverDSL.startNode]. - * @param waitForAllNodesToFinish If true, the nodes will not shut down automatically after executing the code in the driver DSL block. - * It will wait for them to be shut down externally instead. - * @param notarySpecs The notaries advertised for this network. These nodes will be started automatically and will be - * available from [DriverDSL.notaryHandles]. Defaults to a simple validating notary. - * @param jmxPolicy Used to specify whether to expose JMX metrics via Jolokia HHTP/JSON. Defines two attributes: - * startJmxHttpServer: indicates whether the spawned nodes should start with a Jolokia JMX agent to enable remote JMX monitoring using HTTP/JSON. - * jmxHttpServerPortAllocation: the port allocation strategy to use for remote Jolokia/JMX monitoring over HTTP. Defaults to incremental. - * @param dsl The dsl itself. + * @property dsl The dsl itself. * @return The value returned in the [dsl] closure. */ -fun driver( - defaultParameters: DriverParameters = DriverParameters(), - dsl: DriverDSL.() -> A -): A { +fun driver(defaultParameters: DriverParameters = DriverParameters(), dsl: DriverDSL.() -> A): A { return genericDriver( driverDsl = DriverDSLImpl( portAllocation = defaultParameters.portAllocation, @@ -166,7 +152,7 @@ fun driver( extraCordappPackagesToScan = defaultParameters.extraCordappPackagesToScan, jmxPolicy = defaultParameters.jmxPolicy, compatibilityZone = null, - maxTransactionSize = defaultParameters.maxTransactionSize + networkParameters = defaultParameters.networkParameters ), coerce = { it }, dsl = dsl, @@ -174,7 +160,27 @@ fun driver( ) } -/** Helper builder for configuring a [driver] from Java. */ +/** + * Builder for configuring a [driver]. + * @property isDebug Indicates whether the spawned nodes should start in jdwt debug mode and have debug level logging. + * @property driverDirectory The base directory node directories go into, defaults to "build//". The node + * directories themselves are "//", where legalName defaults to "-" + * and may be specified in [DriverDSL.startNode]. + * @property portAllocation The port allocation strategy to use for the messaging and the web server addresses. Defaults + * to incremental. + * @property debugPortAllocation The port allocation strategy to use for jvm debugging. Defaults to incremental. + * @property systemProperties A Map of extra system properties which will be given to each new node. Defaults to empty. + * @property useTestClock If true the test clock will be used in Node. + * @property startNodesInProcess Provides the default behaviour of whether new nodes should start inside this process or + * not. Note that this may be overridden in [DriverDSL.startNode]. + * @property waitForAllNodesToFinish If true, the nodes will not shut down automatically after executing the code in the + * driver DSL block. It will wait for them to be shut down externally instead. + * @property notarySpecs The notaries advertised for this network. These nodes will be started automatically and will be + * available from [DriverDSL.notaryHandles]. Defaults to a simple validating notary. + * @property jmxPolicy Used to specify whether to expose JMX metrics via Jolokia HHTP/JSON. + * @property networkParameters The network parmeters to be used by all the nodes. [NetworkParameters.notaries] must be + * empty as notaries are defined by [notarySpecs]. + */ @Suppress("unused") data class DriverParameters( val isDebug: Boolean = false, @@ -189,18 +195,19 @@ data class DriverParameters( val notarySpecs: List = listOf(NotarySpec(DUMMY_NOTARY_NAME)), val extraCordappPackagesToScan: List = emptyList(), val jmxPolicy: JmxPolicy = JmxPolicy(), - val maxTransactionSize: Int = Int.MAX_VALUE + val networkParameters: NetworkParameters = testNetworkParameters() ) { - fun setIsDebug(isDebug: Boolean) = copy(isDebug = isDebug) - fun setDriverDirectory(driverDirectory: Path) = copy(driverDirectory = driverDirectory) - fun setPortAllocation(portAllocation: PortAllocation) = copy(portAllocation = portAllocation) - fun setDebugPortAllocation(debugPortAllocation: PortAllocation) = copy(debugPortAllocation = debugPortAllocation) - fun setSystemProperties(systemProperties: Map) = copy(systemProperties = systemProperties) - fun setUseTestClock(useTestClock: Boolean) = copy(useTestClock = useTestClock) - fun setInitialiseSerialization(initialiseSerialization: Boolean) = copy(initialiseSerialization = initialiseSerialization) - fun setStartNodesInProcess(startNodesInProcess: Boolean) = copy(startNodesInProcess = startNodesInProcess) - fun setWaitForAllNodesToFinish(waitForAllNodesToFinish: Boolean) = copy(waitForAllNodesToFinish = waitForAllNodesToFinish) - fun setNotarySpecs(notarySpecs: List) = copy(notarySpecs = notarySpecs) - fun setExtraCordappPackagesToScan(extraCordappPackagesToScan: List) = copy(extraCordappPackagesToScan = extraCordappPackagesToScan) - fun setJmxPolicy(jmxPolicy: JmxPolicy) = copy(jmxPolicy = jmxPolicy) -} \ No newline at end of file + fun setIsDebug(isDebug: Boolean): DriverParameters = copy(isDebug = isDebug) + fun setDriverDirectory(driverDirectory: Path): DriverParameters = copy(driverDirectory = driverDirectory) + fun setPortAllocation(portAllocation: PortAllocation): DriverParameters = copy(portAllocation = portAllocation) + fun setDebugPortAllocation(debugPortAllocation: PortAllocation): DriverParameters = copy(debugPortAllocation = debugPortAllocation) + fun setSystemProperties(systemProperties: Map): DriverParameters = copy(systemProperties = systemProperties) + fun setUseTestClock(useTestClock: Boolean): DriverParameters = copy(useTestClock = useTestClock) + fun setInitialiseSerialization(initialiseSerialization: Boolean): DriverParameters = copy(initialiseSerialization = initialiseSerialization) + fun setStartNodesInProcess(startNodesInProcess: Boolean): DriverParameters = copy(startNodesInProcess = startNodesInProcess) + fun setWaitForAllNodesToFinish(waitForAllNodesToFinish: Boolean): DriverParameters = copy(waitForAllNodesToFinish = waitForAllNodesToFinish) + fun setNotarySpecs(notarySpecs: List): DriverParameters = copy(notarySpecs = notarySpecs) + fun setExtraCordappPackagesToScan(extraCordappPackagesToScan: List): DriverParameters = copy(extraCordappPackagesToScan = extraCordappPackagesToScan) + fun setJmxPolicy(jmxPolicy: JmxPolicy): DriverParameters = copy(jmxPolicy = jmxPolicy) + fun setNetworkParameters(networkParameters: NetworkParameters): DriverParameters = copy(networkParameters = networkParameters) +} 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 ad951d99c1..b275c01ba6 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 @@ -6,15 +6,14 @@ 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.node.NetworkParameters import net.corda.core.node.NodeInfo import net.corda.node.VersionInfo import net.corda.node.internal.StartedNode import net.corda.node.services.api.StartedNodeServices import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.messaging.MessagingService -import net.corda.nodeapi.internal.persistence.CordaPersistence -import net.corda.nodeapi.internal.persistence.DatabaseTransaction -import net.corda.nodeapi.internal.persistence.TransactionIsolationLevel +import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.core.DUMMY_NOTARY_NAME import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.internal.setMessagingServiceSpy @@ -53,13 +52,13 @@ data class MockNetworkParameters( val servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random(), val initialiseSerialization: Boolean = true, val notarySpecs: List = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME)), - val maxTransactionSize: Int = Int.MAX_VALUE) { + val networkParameters: NetworkParameters = testNetworkParameters()) { fun setNetworkSendManuallyPumped(networkSendManuallyPumped: Boolean): MockNetworkParameters = copy(networkSendManuallyPumped = networkSendManuallyPumped) fun setThreadPerNode(threadPerNode: Boolean): MockNetworkParameters = copy(threadPerNode = threadPerNode) fun setServicePeerAllocationStrategy(servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy): MockNetworkParameters = copy(servicePeerAllocationStrategy = servicePeerAllocationStrategy) fun setInitialiseSerialization(initialiseSerialization: Boolean): MockNetworkParameters = copy(initialiseSerialization = initialiseSerialization) fun setNotarySpecs(notarySpecs: List): MockNetworkParameters = copy(notarySpecs = notarySpecs) - fun setMaxTransactionSize(maxTransactionSize: Int): MockNetworkParameters = copy(maxTransactionSize = maxTransactionSize) + fun setNetworkParameters(networkParameters: NetworkParameters): MockNetworkParameters = copy(networkParameters = networkParameters) } /** Represents a node configuration for injection via [MockNetworkParameters] **/ @@ -143,11 +142,19 @@ open class MockNetwork( val servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy, val initialiseSerialization: Boolean = defaultParameters.initialiseSerialization, val notarySpecs: List = defaultParameters.notarySpecs, - val maxTransactionSize: Int = defaultParameters.maxTransactionSize) { + val networkParameters: NetworkParameters = defaultParameters.networkParameters) { @JvmOverloads constructor(cordappPackages: List, parameters: MockNetworkParameters = MockNetworkParameters()) : this(cordappPackages, defaultParameters = parameters) - private val internalMockNetwork: InternalMockNetwork = InternalMockNetwork(cordappPackages, defaultParameters, networkSendManuallyPumped, threadPerNode, servicePeerAllocationStrategy, initialiseSerialization, notarySpecs, maxTransactionSize) + private val internalMockNetwork = InternalMockNetwork( + cordappPackages, + defaultParameters, + networkSendManuallyPumped, + threadPerNode, + servicePeerAllocationStrategy, + initialiseSerialization, + notarySpecs, + networkParameters) val defaultNotaryNode get() : StartedMockNode = StartedMockNode.create(internalMockNetwork.defaultNotaryNode) val defaultNotaryIdentity get() : Party = internalMockNetwork.defaultNotaryIdentity val notaryNodes get() : List = internalMockNetwork.notaryNodes.map { StartedMockNode.create(it) } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt index f993b38298..3dd0e0f8be 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt @@ -7,7 +7,6 @@ import net.corda.core.crypto.* import net.corda.core.flows.FlowLogic import net.corda.core.identity.CordaX500Name import net.corda.core.identity.PartyAndCertificate -import net.corda.core.internal.GlobalProperties import net.corda.core.messaging.DataFeed import net.corda.core.messaging.FlowHandle import net.corda.core.messaging.FlowProgressHandle @@ -33,10 +32,11 @@ import net.corda.node.services.vault.NodeVaultService import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.DatabaseConfig import net.corda.nodeapi.internal.persistence.HibernateConfiguration +import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.core.TestIdentity import net.corda.testing.internal.DEV_ROOT_CA -import net.corda.testing.services.MockAttachmentStorage import net.corda.testing.internal.MockCordappProvider +import net.corda.testing.services.MockAttachmentStorage import org.bouncycastle.operator.ContentSigner import rx.Observable import rx.subjects.PublishSubject @@ -62,6 +62,7 @@ open class MockServices private constructor( cordappLoader: CordappLoader, override val validatedTransactions: WritableTransactionStorage, override val identityService: IdentityService, + override val networkParameters: NetworkParameters, private val initialIdentity: TestIdentity, private val moreKeys: Array ) : ServiceHub, StateLoader by validatedTransactions { @@ -95,16 +96,18 @@ open class MockServices private constructor( * @return a pair where the first element is the instance of [CordaPersistence] and the second is [MockServices]. */ @JvmStatic + @JvmOverloads fun makeTestDatabaseAndMockServices(cordappPackages: List, identityService: IdentityService, initialIdentity: TestIdentity, + networkParameters: NetworkParameters = testNetworkParameters(), vararg moreKeys: KeyPair): Pair { val cordappLoader = CordappLoader.createWithTestPackages(cordappPackages) val dataSourceProps = makeTestDataSourceProperties() val schemaService = NodeSchemaService(cordappLoader.cordappSchemas) val database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService, schemaService) val mockService = database.transaction { - object : MockServices(cordappLoader, identityService, initialIdentity, moreKeys) { + object : MockServices(cordappLoader, identityService, networkParameters, initialIdentity, moreKeys) { override val vaultService: VaultServiceInternal = makeVaultService(database.hibernateConfig, schemaService) override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable) { @@ -128,30 +131,43 @@ open class MockServices private constructor( } } - private constructor(cordappLoader: CordappLoader, identityService: IdentityService, + private constructor(cordappLoader: CordappLoader, identityService: IdentityService, networkParameters: NetworkParameters, initialIdentity: TestIdentity, moreKeys: Array) - : this(cordappLoader, MockTransactionStorage(), identityService, initialIdentity, moreKeys) + : this(cordappLoader, MockTransactionStorage(), identityService, networkParameters, initialIdentity, moreKeys) /** * Create a mock [ServiceHub] that looks for app code in the given package names, uses the provided identity service * (you can get one from [makeTestIdentityService]) and represents the given identity. */ @JvmOverloads - constructor(cordappPackages: List, initialIdentity: TestIdentity, identityService: IdentityService = makeTestIdentityService(), vararg moreKeys: KeyPair) : this(CordappLoader.createWithTestPackages(cordappPackages), identityService, initialIdentity, moreKeys) + constructor(cordappPackages: List, + initialIdentity: TestIdentity, + identityService: IdentityService = makeTestIdentityService(), + vararg moreKeys: KeyPair) : + this(CordappLoader.createWithTestPackages(cordappPackages), identityService, testNetworkParameters(), initialIdentity, moreKeys) + + constructor(cordappPackages: List, + initialIdentity: TestIdentity, + identityService: IdentityService, + networkParameters: NetworkParameters, + vararg moreKeys: KeyPair) : + this(CordappLoader.createWithTestPackages(cordappPackages), identityService, networkParameters, initialIdentity, moreKeys) /** * Create a mock [ServiceHub] that looks for app code in the given package names, uses the provided identity service * (you can get one from [makeTestIdentityService]) and represents the given identity. */ @JvmOverloads - constructor(cordappPackages: List, initialIdentityName: CordaX500Name, identityService: IdentityService = makeTestIdentityService(), key: KeyPair, vararg moreKeys: KeyPair) : this(cordappPackages, TestIdentity(initialIdentityName, key), identityService, *moreKeys) + constructor(cordappPackages: List, initialIdentityName: CordaX500Name, identityService: IdentityService = makeTestIdentityService(), key: KeyPair, vararg moreKeys: KeyPair) : + this(cordappPackages, TestIdentity(initialIdentityName, key), identityService, *moreKeys) /** * Create a mock [ServiceHub] that can't load CorDapp code, which uses the provided identity service * (you can get one from [makeTestIdentityService]) and which represents the given identity. */ @JvmOverloads - constructor(cordappPackages: List, initialIdentityName: CordaX500Name, identityService: IdentityService = makeTestIdentityService()) : this(cordappPackages, TestIdentity(initialIdentityName), identityService) + constructor(cordappPackages: List, initialIdentityName: CordaX500Name, identityService: IdentityService = makeTestIdentityService()) : + this(cordappPackages, TestIdentity(initialIdentityName), identityService) /** * Create a mock [ServiceHub] that can't load CorDapp code, and which uses a default service identity. diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeTestUtils.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeTestUtils.kt index 008a0c2e81..dcf47f96b3 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeTestUtils.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeTestUtils.kt @@ -9,13 +9,11 @@ import net.corda.core.context.InvocationContext import net.corda.core.flows.FlowLogic import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party -import net.corda.core.internal.GlobalProperties import net.corda.core.node.ServiceHub import net.corda.core.serialization.internal.effectiveSerializationEnv import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow import net.corda.node.services.api.StartedNodeServices -import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.TestIdentity import net.corda.testing.core.chooseIdentity @@ -36,7 +34,6 @@ fun ServiceHub.ledger( false } return LedgerDSL(TestLedgerDSLInterpreter(this), notary).apply { - GlobalProperties.networkParameters = testNetworkParameters(emptyList()) if (serializationExists) { script() } else { 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 f5978eded5..e7cc449d84 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 @@ -15,6 +15,7 @@ import net.corda.core.identity.CordaX500Name import net.corda.core.internal.* import net.corda.core.internal.concurrent.* import net.corda.core.messaging.CordaRPCOps +import net.corda.core.node.NetworkParameters import net.corda.core.node.NotaryInfo import net.corda.core.node.services.NetworkMapCache import net.corda.core.serialization.deserialize @@ -39,15 +40,14 @@ import net.corda.nodeapi.internal.crypto.X509KeyStore import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.nodeapi.internal.network.NodeInfoFilesCopier -import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.BOB_NAME import net.corda.testing.core.DUMMY_BANK_A_NAME -import net.corda.testing.internal.setGlobalSerialization import net.corda.testing.driver.* import net.corda.testing.driver.internal.InProcessImpl import net.corda.testing.driver.internal.NodeHandleInternal import net.corda.testing.driver.internal.OutOfProcessImpl +import net.corda.testing.internal.setGlobalSerialization import net.corda.testing.node.ClusterSpec import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO import net.corda.testing.node.NotarySpec @@ -92,7 +92,7 @@ class DriverDSLImpl( val jmxPolicy: JmxPolicy, val notarySpecs: List, val compatibilityZone: CompatibilityZoneParams?, - val maxTransactionSize: Int + val networkParameters: NetworkParameters ) : InternalDriverDSL { private var _executorService: ScheduledExecutorService? = null val executorService get() = _executorService!! @@ -387,6 +387,7 @@ class DriverDSLImpl( if (startNodesInProcess) { Schedulers.reset() } + require(networkParameters.notaries.isEmpty()) { "Define notaries using notarySpecs" } _executorService = Executors.newScheduledThreadPool(2, ThreadFactoryBuilder().setNameFormat("driver-pool-thread-%d").build()) _shutdownManager = ShutdownManager(executorService) val notaryInfosFuture = if (compatibilityZone == null) { @@ -704,7 +705,7 @@ class DriverDSLImpl( * The local version of the network map, which is a bunch of classes that copy the relevant files to the node directories. */ private inner class LocalNetworkMap(notaryInfos: List) { - val networkParametersCopier = NetworkParametersCopier(testNetworkParameters(notaryInfos, maxTransactionSize = maxTransactionSize)) + val networkParametersCopier = NetworkParametersCopier(networkParameters.copy(notaries = notaryInfos)) // TODO: this object will copy NodeInfo files from started nodes to other nodes additional-node-infos/ // This uses the FileSystem and adds a delay (~5 seconds) given by the time we wait before polling the file system. // Investigate whether we can avoid that. @@ -966,7 +967,7 @@ fun genericDriver( jmxPolicy = defaultParameters.jmxPolicy, notarySpecs = defaultParameters.notarySpecs, compatibilityZone = null, - maxTransactionSize = defaultParameters.maxTransactionSize + networkParameters = defaultParameters.networkParameters ) ) val shutdownHook = addShutdownHook(driverDsl::shutdown) @@ -1008,7 +1009,7 @@ fun internalDriver( notarySpecs: List = DriverParameters().notarySpecs, extraCordappPackagesToScan: List = DriverParameters().extraCordappPackagesToScan, jmxPolicy: JmxPolicy = DriverParameters().jmxPolicy, - maxTransactionSize: Int = DriverParameters().maxTransactionSize, + networkParameters: NetworkParameters = DriverParameters().networkParameters, compatibilityZone: CompatibilityZoneParams? = null, dsl: DriverDSLImpl.() -> A ): A { @@ -1026,7 +1027,7 @@ fun internalDriver( extraCordappPackagesToScan = extraCordappPackagesToScan, jmxPolicy = jmxPolicy, compatibilityZone = compatibilityZone, - maxTransactionSize = maxTransactionSize + networkParameters = networkParameters ), coerce = { it }, dsl = dsl, 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 b00f4a9db7..d6574593b9 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,6 +18,7 @@ import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.RPCOps import net.corda.core.messaging.SingleMessageRecipient +import net.corda.core.node.NetworkParameters import net.corda.core.node.NodeInfo import net.corda.core.node.NotaryInfo import net.corda.core.node.services.IdentityService @@ -32,11 +33,7 @@ import net.corda.node.internal.StartedNode import net.corda.node.internal.cordapp.CordappLoader import net.corda.node.services.api.NodePropertiesStore import net.corda.node.services.api.SchemaService -import net.corda.node.services.config.BFTSMaRtConfiguration -import net.corda.node.services.config.CertChainPolicyConfig -import net.corda.node.services.config.NodeConfiguration -import net.corda.node.services.config.NotaryConfig -import net.corda.node.services.config.VerifierType +import net.corda.node.services.config.* import net.corda.node.services.keys.E2ETestKeyManagementService import net.corda.node.services.messaging.MessagingService import net.corda.node.services.transactions.BFTNonValidatingNotaryService @@ -51,16 +48,11 @@ 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.internal.rigorousMock +import net.corda.testing.internal.setGlobalSerialization import net.corda.testing.internal.testThreadFactory -import net.corda.testing.node.InMemoryMessagingNetwork -import net.corda.testing.node.MessagingServiceSpy -import net.corda.testing.node.MockNetworkNotarySpec -import net.corda.testing.node.MockNetworkParameters -import net.corda.testing.node.MockNodeParameters +import net.corda.testing.node.* import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties -import net.corda.testing.internal.setGlobalSerialization -import net.corda.testing.node.TestClock import org.apache.activemq.artemis.utils.ReusableLatch import org.apache.sshd.common.util.security.SecurityUtils import rx.internal.schedulers.CachedThreadScheduler @@ -107,13 +99,14 @@ open class InternalMockNetwork(private val cordappPackages: List, servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy, initialiseSerialization: Boolean = defaultParameters.initialiseSerialization, val notarySpecs: List = defaultParameters.notarySpecs, - maxTransactionSize: Int = Int.MAX_VALUE, + networkParameters: NetworkParameters = testNetworkParameters(), val defaultFactory: (MockNodeArgs) -> MockNode = InternalMockNetwork::MockNode) { init { // Apache SSHD for whatever reason registers a SFTP FileSystemProvider - which gets loaded by JimFS. // This SFTP support loads BouncyCastle, which we want to avoid. // Please see https://issues.apache.org/jira/browse/SSHD-736 - it's easier then to create our own fork of SSHD SecurityUtils.setAPrioriDisabledProvider("BC", true) // XXX: Why isn't this static? + require(networkParameters.notaries.isEmpty()) { "Define notaries using notarySpecs" } } var nextNodeId = 0 @@ -123,7 +116,7 @@ open class InternalMockNetwork(private val cordappPackages: List, val messagingNetwork = InMemoryMessagingNetwork.create(networkSendManuallyPumped, servicePeerAllocationStrategy, busyLatch) // A unique identifier for this network to segregate databases with the same nodeID but different networks. private val networkId = random63BitValue() - private val networkParameters: NetworkParametersCopier + private val networkParametersCopier: NetworkParametersCopier private val _nodes = mutableListOf() private val serializationEnv = try { setGlobalSerialization(initialiseSerialization) @@ -199,7 +192,7 @@ open class InternalMockNetwork(private val cordappPackages: List, filesystem.getPath("/nodes").createDirectory() val notaryInfos = generateNotaryIdentities() // The network parameters must be serialised before starting any of the nodes - networkParameters = NetworkParametersCopier(testNetworkParameters(notaryInfos, maxTransactionSize = maxTransactionSize)) + networkParametersCopier = NetworkParametersCopier(networkParameters.copy(notaries = notaryInfos)) @Suppress("LeakingThis") notaryNodes = createNotaries() } catch (t: Throwable) { @@ -251,7 +244,7 @@ open class InternalMockNetwork(private val cordappPackages: List, override val started: StartedNode? get() = uncheckedCast(super.started) override fun start(): StartedNode { - mockNet.networkParameters.install(configuration.baseDirectory) + mockNet.networkParametersCopier.install(configuration.baseDirectory) val started: StartedNode = uncheckedCast(super.start()) advertiseNodeToNetwork(started) return started @@ -269,7 +262,7 @@ open class InternalMockNetwork(private val cordappPackages: List, // We only need to override the messaging service here, as currently everything that hits disk does so // through the java.nio API which we are already mocking via Jimfs. - override fun makeMessagingService(database: CordaPersistence, info: NodeInfo, nodeProperties: NodePropertiesStore): MessagingService { + override fun makeMessagingService(database: CordaPersistence, info: NodeInfo, nodeProperties: NodePropertiesStore, networkParameters: NetworkParameters): MessagingService { require(id >= 0) { "Node ID must be zero or positive, was passed: " + id } return mockNet.messagingNetwork.createNodeWithID( !mockNet.threadPerNode, @@ -317,9 +310,9 @@ open class InternalMockNetwork(private val cordappPackages: List, // Allow unit tests to modify the serialization whitelist list before the node start, // so they don't have to ServiceLoad test whitelists into all unit tests. - val testSerializationWhitelists by lazy { super.serializationWhitelists.toMutableList() } + private val _serializationWhitelists by lazy { super.serializationWhitelists.toMutableList() } override val serializationWhitelists: List - get() = testSerializationWhitelists + get() = _serializationWhitelists private var dbCloser: (() -> Any?)? = null override fun initialiseDatabasePersistence(schemaService: SchemaService, identityService: IdentityService, insideTransaction: (CordaPersistence) -> T): T { return super.initialiseDatabasePersistence(schemaService, identityService) { database -> 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 560a52a865..dd8237450b 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 @@ -53,7 +53,7 @@ abstract class NodeBasedTest(private val cordappPackages: List = emptyLi @Before fun init() { - defaultNetworkParameters = NetworkParametersCopier(testNetworkParameters(emptyList())) + defaultNetworkParameters = NetworkParametersCopier(testNetworkParameters()) } /** diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/RPCDriver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/RPCDriver.kt index e2770f4b80..040f42057d 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/RPCDriver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/RPCDriver.kt @@ -15,6 +15,7 @@ import net.corda.core.internal.concurrent.map import net.corda.core.internal.div import net.corda.core.internal.uncheckedCast import net.corda.core.messaging.RPCOps +import net.corda.core.node.NetworkParameters import net.corda.core.utilities.NetworkHostAndPort import net.corda.node.internal.security.RPCSecurityManagerImpl import net.corda.node.services.messaging.RPCServer @@ -23,6 +24,7 @@ import net.corda.nodeapi.ArtemisTcpTransport import net.corda.nodeapi.ConnectionDirection import net.corda.nodeapi.RPCApi import net.corda.nodeapi.internal.serialization.KRYO_RPC_CLIENT_CONTEXT +import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.core.MAX_MESSAGE_SIZE import net.corda.testing.driver.JmxPolicy import net.corda.testing.driver.PortAllocation @@ -106,7 +108,7 @@ fun rpcDriver( notarySpecs: List = emptyList(), externalTrace: Trace? = null, jmxPolicy: JmxPolicy = JmxPolicy(), - maxTransactionSize: Int = Int.MAX_VALUE, + networkParameters: NetworkParameters = testNetworkParameters(), dsl: RPCDriverDSL.() -> A ): A { return genericDriver( @@ -124,7 +126,7 @@ fun rpcDriver( notarySpecs = notarySpecs, jmxPolicy = jmxPolicy, compatibilityZone = null, - maxTransactionSize = maxTransactionSize + networkParameters = networkParameters ), externalTrace ), coerce = { it }, @@ -157,7 +159,7 @@ data class RPCDriverDSL( private val driverDSL: DriverDSLImpl, private val externalTrace: Trace? ) : InternalDriverDSL by driverDSL { private companion object { - val notificationAddress = "notifications" + const val notificationAddress = "notifications" private fun ConfigurationImpl.configureCommonSettings(maxFileSize: Int, maxBufferedBytesPerClient: Long) { managementNotificationAddress = SimpleString(notificationAddress) diff --git a/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt b/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt index 38ebfc9d2b..11ec0e7bb7 100644 --- a/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt +++ b/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt @@ -9,8 +9,8 @@ import net.corda.core.internal.div import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.contextLogger import net.corda.nodeapi.internal.network.NetworkParametersCopier -import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.asContextEnv +import net.corda.testing.common.internal.testNetworkParameters import java.net.URL import java.nio.file.Path import java.nio.file.Paths @@ -51,8 +51,8 @@ class NodeProcess( // TODO All use of this factory have duplicate code which is either bundling the calling module or a 3rd party module // as a CorDapp for the nodes. class Factory( - val buildDirectory: Path = Paths.get("build"), - val cordaJarUrl: URL? = this::class.java.getResource("/corda.jar") + private val buildDirectory: Path = Paths.get("build"), + private val cordaJarUrl: URL? = this::class.java.getResource("/corda.jar") ) { val cordaJar: Path by lazy { require(cordaJarUrl != null, { "corda.jar could not be found in classpath" }) @@ -66,7 +66,7 @@ class NodeProcess( KryoClientSerializationScheme.createSerializationEnv().asContextEnv { // There are no notaries in the network parameters for smoke test nodes. If this is required then we would // need to introduce the concept of a "network" which predefines the notaries, like the driver and MockNetwork - NetworkParametersCopier(testNetworkParameters(emptyList())) + NetworkParametersCopier(testNetworkParameters()) } } diff --git a/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/ParametersUtilities.kt b/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/ParametersUtilities.kt index ea089257c2..322e9e90b7 100644 --- a/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/ParametersUtilities.kt +++ b/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/ParametersUtilities.kt @@ -5,12 +5,12 @@ import net.corda.core.node.NotaryInfo import java.time.Instant fun testNetworkParameters( - notaries: List, + notaries: List = emptyList(), minimumPlatformVersion: Int = 1, modifiedTime: Instant = Instant.now(), maxMessageSize: Int = 10485760, // TODO: Make this configurable and consistence across driver, bootstrapper, demobench and NetworkMapServer - maxTransactionSize: Int = Int.MAX_VALUE, + maxTransactionSize: Int = maxMessageSize, epoch: Int = 1 ): NetworkParameters { return NetworkParameters( diff --git a/verifier/src/integration-test/kotlin/net/corda/verifier/GeneratedLedger.kt b/verifier/src/integration-test/kotlin/net/corda/verifier/GeneratedLedger.kt index afc019ed9a..a07bc0c1ea 100644 --- a/verifier/src/integration-test/kotlin/net/corda/verifier/GeneratedLedger.kt +++ b/verifier/src/integration-test/kotlin/net/corda/verifier/GeneratedLedger.kt @@ -1,17 +1,27 @@ package net.corda.verifier +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.doAnswer +import com.nhaarman.mockito_kotlin.whenever import net.corda.client.mock.Generator import net.corda.core.contracts.* +import net.corda.core.cordapp.CordappProvider import net.corda.core.crypto.SecureHash import net.corda.core.crypto.entropyToKeyPair import net.corda.core.identity.AbstractParty import net.corda.core.identity.AnonymousParty import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party +import net.corda.core.node.NetworkParameters +import net.corda.core.node.ServicesForResolution +import net.corda.core.node.services.AttachmentStorage +import net.corda.core.node.services.IdentityService import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.WireTransaction import net.corda.nodeapi.internal.serialization.GeneratedAttachment +import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.contracts.DummyContract +import net.corda.testing.internal.rigorousMock import org.apache.commons.lang.ArrayUtils.EMPTY_BYTE_ARRAY import java.math.BigInteger import java.security.PublicKey @@ -29,25 +39,36 @@ data class GeneratedLedger( val attachments: Set, val identities: Set ) { - val hashTransactionMap: Map by lazy { transactions.associateBy(WireTransaction::id) } - val attachmentMap: Map by lazy { attachments.associateBy(Attachment::id) } - val identityMap: Map by lazy { identities.associateBy(Party::owningKey) } - val contractAttachmentMap: Map by lazy { + private val hashTransactionMap: Map by lazy { transactions.associateBy(WireTransaction::id) } + private val attachmentMap: Map by lazy { attachments.associateBy(Attachment::id) } + private val identityMap: Map by lazy { identities.associateBy(Party::owningKey) } + private val contractAttachmentMap: Map by lazy { attachments.mapNotNull { it as? ContractAttachment }.associateBy { it.contract } } + private val services = object : ServicesForResolution { + override fun loadState(stateRef: StateRef): TransactionState<*> { + return hashTransactionMap[stateRef.txhash]?.outputs?.get(stateRef.index) ?: throw TransactionResolutionException(stateRef.txhash) + } + override val identityService = rigorousMock().apply { + doAnswer { identityMap[it.arguments[0]] }.whenever(this).partyFromKey(any()) + } + override val attachments = rigorousMock().apply { + doAnswer { attachmentMap[it.arguments[0]] }.whenever(this).openAttachment(any()) + } + override val cordappProvider = rigorousMock().apply { + doAnswer { contractAttachmentMap[it.arguments[0]]?.id }.whenever(this).getContractAttachmentID(any()) + } + override val networkParameters = testNetworkParameters() + } + companion object { val empty = GeneratedLedger(emptyList(), emptyMap(), emptySet(), emptySet()) val contractAttachment = ContractAttachment(GeneratedAttachment(EMPTY_BYTE_ARRAY), DummyContract.PROGRAM_ID) } fun resolveWireTransaction(transaction: WireTransaction): LedgerTransaction { - return transaction.toLedgerTransaction( - resolveIdentity = { identityMap[it] }, - resolveAttachment = { attachmentMap[it] }, - resolveStateRef = { hashTransactionMap[it.txhash]?.outputs?.get(it.index) }, - resolveContractAttachment = { contractAttachmentMap[it.contract]?.id } - ) + return transaction.toLedgerTransaction(services) } val attachmentsGenerator: Generator> by lazy { diff --git a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt index 50c1b8d7e1..d9c6fcef06 100644 --- a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt +++ b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt @@ -5,13 +5,13 @@ import com.typesafe.config.ConfigFactory import net.corda.core.concurrent.CordaFuture import net.corda.core.crypto.random63BitValue import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.GlobalProperties import net.corda.core.internal.concurrent.OpenFuture import net.corda.core.internal.concurrent.doneFuture import net.corda.core.internal.concurrent.fork import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.createDirectories import net.corda.core.internal.div +import net.corda.core.node.NetworkParameters import net.corda.core.serialization.internal.nodeSerializationEnv import net.corda.core.transactions.LedgerTransaction import net.corda.core.utilities.NetworkHostAndPort @@ -64,7 +64,7 @@ fun verifierDriver( extraCordappPackagesToScan: List = emptyList(), notarySpecs: List = emptyList(), jmxPolicy: JmxPolicy = JmxPolicy(), - maxTransactionSize: Int = Int.MAX_VALUE, + networkParameters: NetworkParameters = testNetworkParameters(), dsl: VerifierDriverDSL.() -> A ) = genericDriver( driverDsl = VerifierDriverDSL( @@ -81,7 +81,7 @@ fun verifierDriver( notarySpecs = notarySpecs, jmxPolicy = jmxPolicy, compatibilityZone = null, - maxTransactionSize = maxTransactionSize + networkParameters = networkParameters ) ), coerce = { it }, @@ -167,7 +167,6 @@ data class VerifierDriverDSL(private val driverDSL: DriverDSLImpl) : InternalDri /** Starts a lightweight verification requestor that implements the Node's Verifier API */ fun startVerificationRequestor(name: CordaX500Name): CordaFuture { val hostAndPort = driverDSL.portAllocation.nextHostAndPort() - GlobalProperties.networkParameters = testNetworkParameters(emptyList(), maxTransactionSize = driverDSL.maxTransactionSize) return driverDSL.executorService.fork { startVerificationRequestorInternal(name, hostAndPort) }