mirror of
https://github.com/corda/corda.git
synced 2024-12-19 13:08:04 +00:00
[CORDA-1445]: Raise proper error when starting node in devMode with compatibilityZoneURL. (#3109)
This commit is contained in:
parent
15e87050c7
commit
5e0b27cfae
@ -6,6 +6,8 @@ release, see :doc:`upgrade-notes`.
|
||||
|
||||
Unreleased
|
||||
==========
|
||||
* Node will now gracefully fail to start if ``devMode`` is true and ``compatibilityZoneURL`` is specified.
|
||||
|
||||
* Fixed an error thrown by NodeVaultService upon recording a transaction with a number of inputs greater than the default page size.
|
||||
|
||||
* Fixed incorrect computation of ``totalStates`` from ``otherResults`` in ``NodeVaultService``.
|
||||
|
@ -1,23 +1,37 @@
|
||||
package net.corda.node.services.network
|
||||
|
||||
import net.corda.cordform.CordformNode
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.internal.*
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.bufferUntilSubscribed
|
||||
import net.corda.core.internal.concurrent.transpose
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.internal.exists
|
||||
import net.corda.core.internal.list
|
||||
import net.corda.core.internal.readObject
|
||||
import net.corda.core.messaging.ParametersUpdateInfo
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.node.services.config.configureDevKeyAndTrustStores
|
||||
import net.corda.nodeapi.internal.config.NodeSSLConfiguration
|
||||
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_FILE_NAME
|
||||
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME
|
||||
import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
||||
import net.corda.testing.common.internal.testNetworkParameters
|
||||
import net.corda.testing.core.*
|
||||
import net.corda.testing.core.ALICE_NAME
|
||||
import net.corda.testing.core.BOB_NAME
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
import net.corda.testing.core.expect
|
||||
import net.corda.testing.core.expectEvents
|
||||
import net.corda.testing.core.sequence
|
||||
import net.corda.testing.driver.NodeHandle
|
||||
import net.corda.testing.driver.internal.NodeHandleInternal
|
||||
import net.corda.testing.driver.internal.RandomFree
|
||||
import net.corda.testing.node.internal.CompatibilityZoneParams
|
||||
import net.corda.testing.node.internal.DriverDSLImpl
|
||||
import net.corda.testing.node.internal.internalDriver
|
||||
import net.corda.testing.node.internal.network.NetworkMapServer
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@ -63,7 +77,7 @@ class NetworkMapTest {
|
||||
initialiseSerialization = false,
|
||||
notarySpecs = emptyList()
|
||||
) {
|
||||
val alice = startNode(providedName = ALICE_NAME).getOrThrow() as NodeHandleInternal
|
||||
val alice = startNode(providedName = ALICE_NAME, devMode = false).getOrThrow() as NodeHandleInternal
|
||||
val nextParams = networkMapServer.networkParameters.copy(epoch = 3, modifiedTime = Instant.ofEpochMilli(random63BitValue()))
|
||||
val nextHash = nextParams.serialize().hash
|
||||
val snapshot = alice.rpc.networkParametersFeed().snapshot
|
||||
@ -110,7 +124,7 @@ class NetworkMapTest {
|
||||
initialiseSerialization = false,
|
||||
notarySpecs = emptyList()
|
||||
) {
|
||||
val alice = startNode(providedName = ALICE_NAME).getOrThrow()
|
||||
val alice = startNode(providedName = ALICE_NAME, devMode = false).getOrThrow()
|
||||
val networkParameters = (alice.baseDirectory / NETWORK_PARAMS_FILE_NAME)
|
||||
.readObject<SignedNetworkParameters>()
|
||||
.verified()
|
||||
@ -125,17 +139,16 @@ class NetworkMapTest {
|
||||
internalDriver(
|
||||
portAllocation = portAllocation,
|
||||
compatibilityZone = compatibilityZone,
|
||||
initialiseSerialization = false
|
||||
initialiseSerialization = false,
|
||||
notarySpecs = emptyList()
|
||||
) {
|
||||
val (aliceNode, bobNode, notaryNode) = listOf(
|
||||
startNode(providedName = ALICE_NAME),
|
||||
startNode(providedName = BOB_NAME),
|
||||
defaultNotaryNode
|
||||
val (aliceNode, bobNode) = listOf(
|
||||
startNode(providedName = ALICE_NAME, devMode = false),
|
||||
startNode(providedName = BOB_NAME, devMode = false)
|
||||
).transpose().getOrThrow()
|
||||
|
||||
notaryNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
aliceNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
bobNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
aliceNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
bobNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,24 +157,20 @@ class NetworkMapTest {
|
||||
internalDriver(
|
||||
portAllocation = portAllocation,
|
||||
compatibilityZone = compatibilityZone,
|
||||
initialiseSerialization = false
|
||||
initialiseSerialization = false,
|
||||
notarySpecs = emptyList()
|
||||
) {
|
||||
val (aliceNode, notaryNode) = listOf(
|
||||
startNode(providedName = ALICE_NAME),
|
||||
defaultNotaryNode
|
||||
).transpose().getOrThrow()
|
||||
val aliceNode = startNode(providedName = ALICE_NAME, devMode = false).getOrThrow()
|
||||
|
||||
notaryNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo)
|
||||
aliceNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo)
|
||||
aliceNode.onlySees(aliceNode.nodeInfo)
|
||||
|
||||
val bobNode = startNode(providedName = BOB_NAME).getOrThrow()
|
||||
val bobNode = startNode(providedName = BOB_NAME, devMode = false).getOrThrow()
|
||||
|
||||
// Wait for network map client to poll for the next update.
|
||||
Thread.sleep(cacheTimeout.toMillis() * 2)
|
||||
|
||||
bobNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
notaryNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
aliceNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
bobNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
aliceNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,25 +179,23 @@ class NetworkMapTest {
|
||||
internalDriver(
|
||||
portAllocation = portAllocation,
|
||||
compatibilityZone = compatibilityZone,
|
||||
initialiseSerialization = false
|
||||
initialiseSerialization = false,
|
||||
notarySpecs = emptyList()
|
||||
) {
|
||||
val (aliceNode, bobNode, notaryNode) = listOf(
|
||||
startNode(providedName = ALICE_NAME),
|
||||
startNode(providedName = BOB_NAME),
|
||||
defaultNotaryNode
|
||||
val (aliceNode, bobNode) = listOf(
|
||||
startNode(providedName = ALICE_NAME, devMode = false),
|
||||
startNode(providedName = BOB_NAME, devMode = false)
|
||||
).transpose().getOrThrow()
|
||||
|
||||
notaryNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
aliceNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
bobNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
aliceNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
bobNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
|
||||
|
||||
networkMapServer.removeNodeInfo(aliceNode.nodeInfo)
|
||||
|
||||
// Wait for network map client to poll for the next update.
|
||||
Thread.sleep(cacheTimeout.toMillis() * 2)
|
||||
|
||||
notaryNode.onlySees(notaryNode.nodeInfo, bobNode.nodeInfo)
|
||||
bobNode.onlySees(notaryNode.nodeInfo, bobNode.nodeInfo)
|
||||
bobNode.onlySees(bobNode.nodeInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,3 +208,19 @@ class NetworkMapTest {
|
||||
assertThat(rpc.networkMapSnapshot()).containsOnly(*nodes)
|
||||
}
|
||||
}
|
||||
|
||||
private fun DriverDSLImpl.startNode(providedName: CordaX500Name, devMode: Boolean): CordaFuture<NodeHandle> {
|
||||
var customOverrides = emptyMap<String, String>()
|
||||
if (!devMode) {
|
||||
val nodeDir = baseDirectory(providedName)
|
||||
val nodeSslConfig = object : NodeSSLConfiguration {
|
||||
override val baseDirectory = nodeDir
|
||||
override val keyStorePassword = "cordacadevpass"
|
||||
override val trustStorePassword = "trustpass"
|
||||
override val crlCheckSoftFail = true
|
||||
}
|
||||
nodeSslConfig.configureDevKeyAndTrustStores(providedName)
|
||||
customOverrides = mapOf("devMode" to "false")
|
||||
}
|
||||
return startNode(providedName = providedName, customOverrides = customOverrides)
|
||||
}
|
||||
|
@ -180,6 +180,7 @@ data class NodeConfigurationImpl(
|
||||
|
||||
override fun validate(): List<String> {
|
||||
val errors = mutableListOf<String>()
|
||||
errors += validateDevModeOptions()
|
||||
errors += validateRpcOptions(rpcOptions)
|
||||
return errors
|
||||
}
|
||||
@ -194,6 +195,16 @@ data class NodeConfigurationImpl(
|
||||
return errors
|
||||
}
|
||||
|
||||
private fun validateDevModeOptions(): List<String> {
|
||||
val errors = mutableListOf<String>()
|
||||
if (devMode) {
|
||||
compatibilityZoneURL?.let {
|
||||
errors += "'compatibilityZoneURL': present. Property cannot be set when 'devMode' is true."
|
||||
}
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
override val transactionCacheSizeBytes: Long
|
||||
get() = transactionCacheSizeMegaBytes?.MB ?: super.transactionCacheSizeBytes
|
||||
override val attachmentContentCacheSizeBytes: Long
|
||||
|
@ -6,8 +6,10 @@ import net.corda.core.utilities.seconds
|
||||
import net.corda.testing.core.ALICE_NAME
|
||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||
import net.corda.tools.shell.SSHDConfiguration
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.junit.Test
|
||||
import java.net.URI
|
||||
import java.nio.file.Paths
|
||||
import java.util.*
|
||||
import kotlin.test.assertFalse
|
||||
@ -43,6 +45,15 @@ class NodeConfigurationImplTest {
|
||||
assertFalse { testConfiguration.copy(noLocalShell = true, sshd = null).shouldInitCrashShell() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validation has error when compatibilityZoneURL is present and devMode is true`() {
|
||||
val configuration = testConfiguration.copy(devMode = true, compatibilityZoneURL = URI.create("https://r3.com").toURL())
|
||||
|
||||
val errors = configuration.validate()
|
||||
|
||||
assertThat(errors).hasOnlyOneElementSatisfying { error -> error.contains("compatibilityZoneURL") && error.contains("devMode") }
|
||||
}
|
||||
|
||||
private fun configDebugOptions(devMode: Boolean, devModeOptions: DevModeOptions?): NodeConfiguration {
|
||||
return testConfiguration.copy(devMode = devMode, devModeOptions = devModeOptions)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user