[CORDA-1445]: Raise proper error when starting node in devMode with compatibilityZoneURL. (#3109)

This commit is contained in:
Michele Sollecito 2018-05-10 22:00:47 +07:00 committed by GitHub
parent 15e87050c7
commit 5e0b27cfae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 80 additions and 33 deletions

View File

@ -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``.

View File

@ -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)
}

View File

@ -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

View File

@ -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)
}