From c08f65a92cd76395833a25f723eec4d61b538ae2 Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Thu, 27 Dec 2018 14:21:37 +0000 Subject: [PATCH] CORDA-2128: Moved all the helper methods added to NetworkParameters.kt into internal (#4466) --- .../net/corda/core/internal/CordaUtils.kt | 37 +++++- .../net/corda/core/node/NetworkParameters.kt | 118 +++++------------- .../corda/core/node/NetworkParametersTest.kt | 43 +------ .../services/network/NetworkMapUpdater.kt | 32 ++++- .../services/network/NetworkMapUpdaterTest.kt | 48 +++++-- .../NetworkParameterOverridesSpec.kt | 11 +- 6 files changed, 144 insertions(+), 145 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt b/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt index 099e47e6d4..f6c97377b8 100644 --- a/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt +++ b/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt @@ -1,12 +1,14 @@ package net.corda.core.internal import net.corda.core.DeleteForDJVM +import net.corda.core.contracts.ContractClassName import net.corda.core.cordapp.Cordapp import net.corda.core.cordapp.CordappConfig import net.corda.core.cordapp.CordappContext import net.corda.core.crypto.SecureHash import net.corda.core.flows.DataVendingFlow import net.corda.core.flows.FlowLogic +import net.corda.core.node.NetworkParameters import net.corda.core.node.ServicesForResolution import net.corda.core.node.ZoneVersionTooLowException import net.corda.core.serialization.CordaSerializable @@ -16,6 +18,7 @@ import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.WireTransaction import org.slf4j.MDC +import java.security.PublicKey // *Internal* Corda-specific utilities. @@ -71,9 +74,7 @@ private fun isPackageValid(packageName: String): Boolean { } } -/** - * Check if a string is a legal Java package name. - */ +/** Check if a string is a legal Java package name. */ fun requirePackageValid(name: String) { require(isPackageValid(name)) { "Invalid Java package name: `$name`." } } @@ -85,3 +86,33 @@ fun requirePackageValid(name: String) { */ @CordaSerializable object RetrieveAnyTransactionPayload : ArrayList() + +/** + * Returns true if the [fullClassName] is in a subpackage of [packageName]. + * E.g.: "com.megacorp" owns "com.megacorp.tokens.MegaToken" + * + * Note: The ownership check is ignoring case to prevent people from just releasing a jar with: "com.megaCorp.megatoken" and pretend they are MegaCorp. + * By making the check case insensitive, the node will require that the jar is signed by MegaCorp, so the attack fails. + */ +private fun owns(packageName: String, fullClassName: String): Boolean = fullClassName.startsWith("$packageName.", ignoreCase = true) + +/** Returns the public key of the package owner of the [contractClassName], or null if not owned. */ +internal fun NetworkParameters.getPackageOwnerOf(contractClassName: ContractClassName): PublicKey? { + return packageOwnership.entries.singleOrNull { owns(it.key, contractClassName) }?.value +} + +/** + * Returns the public key of the package owner if any of [contractClassNames] match, or null if not owned. + */ +internal fun NetworkParameters.getPackageOwnerOf(contractClassNames: Set): PublicKey? { + for (contractClassName in contractClassNames) { + val owner = getPackageOwnerOf(contractClassName) + if (owner != null) return owner + } + return null +} + +// Make sure that packages don't overlap so that ownership is clear. +fun noPackageOverlap(packages: Collection): Boolean { + return packages.all { outer -> packages.none { inner -> inner != outer && inner.startsWith("$outer.") } } +} diff --git a/core/src/main/kotlin/net/corda/core/node/NetworkParameters.kt b/core/src/main/kotlin/net/corda/core/node/NetworkParameters.kt index 5e7c4857a1..113feeda06 100644 --- a/core/src/main/kotlin/net/corda/core/node/NetworkParameters.kt +++ b/core/src/main/kotlin/net/corda/core/node/NetworkParameters.kt @@ -2,23 +2,17 @@ package net.corda.core.node import net.corda.core.CordaRuntimeException import net.corda.core.KeepForDJVM -import net.corda.core.contracts.ContractClassName import net.corda.core.crypto.toStringShort import net.corda.core.identity.Party -import net.corda.core.internal.VisibleForTesting +import net.corda.core.internal.noPackageOverlap import net.corda.core.internal.requirePackageValid import net.corda.core.node.services.AttachmentId import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.DeprecatedConstructorForDeserialization import net.corda.core.utilities.days -import java.lang.reflect.Method import java.security.PublicKey import java.time.Duration import java.time.Instant -import kotlin.reflect.KProperty1 -import kotlin.reflect.full.declaredMemberProperties -import kotlin.reflect.full.findAnnotation -import kotlin.reflect.jvm.javaGetter // DOCSTART 1 /** @@ -54,13 +48,13 @@ data class NetworkParameters( ) { // DOCEND 1 @DeprecatedConstructorForDeserialization(1) - constructor (minimumPlatformVersion: Int, - notaries: List, - maxMessageSize: Int, - maxTransactionSize: Int, - modifiedTime: Instant, - epoch: Int, - whitelistedContractImplementations: Map> + constructor(minimumPlatformVersion: Int, + notaries: List, + maxMessageSize: Int, + maxTransactionSize: Int, + modifiedTime: Instant, + epoch: Int, + whitelistedContractImplementations: Map> ) : this(minimumPlatformVersion, notaries, maxMessageSize, @@ -73,14 +67,14 @@ data class NetworkParameters( ) @DeprecatedConstructorForDeserialization(2) - constructor (minimumPlatformVersion: Int, - notaries: List, - maxMessageSize: Int, - maxTransactionSize: Int, - modifiedTime: Instant, - epoch: Int, - whitelistedContractImplementations: Map>, - eventHorizon: Duration + constructor(minimumPlatformVersion: Int, + notaries: List, + maxMessageSize: Int, + maxTransactionSize: Int, + modifiedTime: Instant, + epoch: Int, + whitelistedContractImplementations: Map>, + eventHorizon: Duration ) : this(minimumPlatformVersion, notaries, maxMessageSize, @@ -92,32 +86,6 @@ data class NetworkParameters( emptyMap() ) - companion object { - private val memberPropertyPartition = NetworkParameters::class.declaredMemberProperties.asSequence() - .partition { it.isAutoAcceptable() } - private val autoAcceptableNamesAndGetters = memberPropertyPartition.first.associateBy({ it.name }, { it.javaGetter }) - private val nonAutoAcceptableGetters = memberPropertyPartition.second.map { it.javaGetter } - val autoAcceptablePropertyNames = autoAcceptableNamesAndGetters.keys - - /** - * Returns true if the [fullClassName] is in a subpackage of [packageName]. - * E.g.: "com.megacorp" owns "com.megacorp.tokens.MegaToken" - * - * Note: The ownership check is ignoring case to prevent people from just releasing a jar with: "com.megaCorp.megatoken" and pretend they are MegaCorp. - * By making the check case insensitive, the node will require that the jar is signed by MegaCorp, so the attack fails. - */ - private fun owns(packageName: String, fullClassName: String) = fullClassName.startsWith("$packageName.", ignoreCase = true) - - // Make sure that packages don't overlap so that ownership is clear. - fun noOverlap(packages: Collection) = packages.all { currentPackage -> - packages.none { otherPackage -> otherPackage != currentPackage && otherPackage.startsWith("$currentPackage.") } - } - - private fun KProperty1.isAutoAcceptable(): Boolean { - return this.findAnnotation() != null - } - } - init { require(minimumPlatformVersion > 0) { "Minimum platform level must be at least 1" } require(notaries.distinctBy { it.identity } == notaries) { "Duplicate notary identities" } @@ -126,7 +94,7 @@ data class NetworkParameters( require(maxTransactionSize > 0) { "Maximum transaction size must be at least 1" } require(!eventHorizon.isNegative) { "Event Horizon must be a positive value" } packageOwnership.keys.forEach(::requirePackageValid) - require(noOverlap(packageOwnership.keys)) { "Multiple packages added to the packageOwnership overlap." } + require(noPackageOverlap(packageOwnership.keys)) { "Multiple packages added to the packageOwnership overlap." } } fun copy(minimumPlatformVersion: Int, @@ -137,14 +105,16 @@ data class NetworkParameters( epoch: Int, whitelistedContractImplementations: Map> ): NetworkParameters { - return copy(minimumPlatformVersion = minimumPlatformVersion, + return copy( + minimumPlatformVersion = minimumPlatformVersion, notaries = notaries, maxMessageSize = maxMessageSize, maxTransactionSize = maxTransactionSize, modifiedTime = modifiedTime, epoch = epoch, whitelistedContractImplementations = whitelistedContractImplementations, - eventHorizon = eventHorizon) + eventHorizon = eventHorizon + ) } fun copy(minimumPlatformVersion: Int, @@ -156,14 +126,16 @@ data class NetworkParameters( whitelistedContractImplementations: Map>, eventHorizon: Duration ): NetworkParameters { - return copy(minimumPlatformVersion = minimumPlatformVersion, + return copy( + minimumPlatformVersion = minimumPlatformVersion, notaries = notaries, maxMessageSize = maxMessageSize, maxTransactionSize = maxTransactionSize, modifiedTime = modifiedTime, epoch = epoch, whitelistedContractImplementations = whitelistedContractImplementations, - eventHorizon = eventHorizon) + eventHorizon = eventHorizon + ) } override fun toString(): String { @@ -176,43 +148,13 @@ data class NetworkParameters( ${whitelistedContractImplementations.entries.joinToString("\n ")} } eventHorizon=$eventHorizon - modifiedTime=$modifiedTime - epoch=$epoch, - packageOwnership= { + packageOwnership { ${packageOwnership.entries.joinToString("\n ") { "$it.key -> ${it.value.toStringShort()}" }} } + modifiedTime=$modifiedTime + epoch=$epoch }""" } - - /** - * Returns the public key of the package owner of the [contractClassName], or null if not owned. - */ - @VisibleForTesting - internal fun getPackageOwnerOf(contractClassName: ContractClassName): PublicKey? = this.packageOwnership.filterKeys { packageName -> owns(packageName, contractClassName) }.values.singleOrNull() - - /** - * Returns the public key of the package owner if any of [contractClassName] match, or null if not owned. - */ - @VisibleForTesting - internal fun getPackageOwnerOf(contractClassNames: Set): PublicKey? { - val ownerKeys = contractClassNames.map { getPackageOwnerOf(it) } - return ownerKeys.find { it != null } - } - - /** - * Returns true if the only properties changed in [newNetworkParameters] are [AutoAcceptable] and not - * included in the [excludedParameterNames] - */ - fun canAutoAccept(newNetworkParameters: NetworkParameters, excludedParameterNames: Set): Boolean { - return nonAutoAcceptableGetters.none { valueChanged(newNetworkParameters, it) } && - autoAcceptableNamesAndGetters.none { excludedParameterNames.contains(it.key) && valueChanged(newNetworkParameters, it.value) } - } - - private fun valueChanged(newNetworkParameters: NetworkParameters, getter: Method?): Boolean { - val propertyValue = getter?.invoke(this) - val newPropertyValue = getter?.invoke(newNetworkParameters) - return propertyValue != newPropertyValue - } } /** @@ -229,7 +171,3 @@ data class NotaryInfo(val identity: Party, val validating: Boolean) * version. */ class ZoneVersionTooLowException(message: String) : CordaRuntimeException(message) - -private fun KProperty1.isAutoAcceptable(): Boolean { - return this.findAnnotation() != null -} \ No newline at end of file diff --git a/core/src/test/kotlin/net/corda/core/node/NetworkParametersTest.kt b/core/src/test/kotlin/net/corda/core/node/NetworkParametersTest.kt index 2a6e8e1c46..6639d8002a 100644 --- a/core/src/test/kotlin/net/corda/core/node/NetworkParametersTest.kt +++ b/core/src/test/kotlin/net/corda/core/node/NetworkParametersTest.kt @@ -1,7 +1,7 @@ package net.corda.core.node import net.corda.core.crypto.generateKeyPair -import net.corda.core.node.services.AttachmentId +import net.corda.core.internal.getPackageOwnerOf import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.days import net.corda.core.utilities.getOrThrow @@ -32,7 +32,8 @@ import kotlin.test.assertFails class NetworkParametersTest { private val mockNet = InternalMockNetwork( defaultParameters = MockNetworkParameters(networkSendManuallyPumped = true), - notarySpecs = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME))) + notarySpecs = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME)) + ) @After fun tearDown() { @@ -129,44 +130,8 @@ class NetworkParametersTest { assertEquals(params.getPackageOwnerOf("com.exam.something.MyClass"), null) } - @Test - fun `auto acceptance checks are correct`() { - val packageOwnership = mapOf( - "com.example1" to generateKeyPair().public, - "com.example2" to generateKeyPair().public) - val whitelistedContractImplementations = mapOf( - "example1" to listOf(AttachmentId.randomSHA256()), - "example2" to listOf(AttachmentId.randomSHA256())) - - val netParams = testNetworkParameters() - val netParamsAutoAcceptable = netParams.copy( - packageOwnership = packageOwnership, - whitelistedContractImplementations = whitelistedContractImplementations) - val netParamsNotAutoAcceptable = netParamsAutoAcceptable.copy( - maxMessageSize = netParams.maxMessageSize + 1) - - assert(netParams.canAutoAccept(netParams, emptySet())) { - "auto-acceptable if identical" - } - assert(netParams.canAutoAccept(netParams, NetworkParameters.autoAcceptablePropertyNames)) { - "auto acceptable if identical regardless of exclusions" - } - assert(netParams.canAutoAccept(netParamsAutoAcceptable, emptySet())) { - "auto-acceptable if only AutoAcceptable params have changed" - } - assert(netParams.canAutoAccept(netParamsAutoAcceptable, setOf("modifiedTime"))) { - "auto-acceptable if only AutoAcceptable params have changed and excluded param has not changed" - } - assert(!netParams.canAutoAccept(netParamsNotAutoAcceptable, emptySet())) { - "not auto-acceptable if non-AutoAcceptable param has changed" - } - assert(!netParams.canAutoAccept(netParamsAutoAcceptable, setOf("whitelistedContractImplementations"))) { - "not auto-acceptable if only AutoAcceptable params have changed but one has been added to the exclusion set" - } - } - // Helpers private fun dropParametersToDir(dir: Path, params: NetworkParameters) { NetworkParametersCopier(params).install(dir) } -} \ No newline at end of file +} diff --git a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapUpdater.kt b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapUpdater.kt index 72cdabcd7e..899cb975c9 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapUpdater.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapUpdater.kt @@ -7,6 +7,7 @@ import net.corda.core.crypto.SignedData import net.corda.core.internal.* import net.corda.core.messaging.DataFeed import net.corda.core.messaging.ParametersUpdateInfo +import net.corda.core.node.AutoAcceptable import net.corda.core.node.NetworkParameters import net.corda.core.node.services.KeyManagementService import net.corda.core.serialization.serialize @@ -21,6 +22,7 @@ import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.network.* import rx.Subscription import rx.subjects.PublishSubject +import java.lang.reflect.Method import java.nio.file.Path import java.nio.file.StandardCopyOption import java.security.cert.X509Certificate @@ -28,6 +30,10 @@ import java.time.Duration import java.util.* import java.util.concurrent.ScheduledThreadPoolExecutor import java.util.concurrent.TimeUnit +import kotlin.reflect.KProperty1 +import kotlin.reflect.full.declaredMemberProperties +import kotlin.reflect.full.findAnnotation +import kotlin.reflect.jvm.javaGetter import kotlin.system.exitProcess class NetworkMapUpdater(private val networkMapCache: NetworkMapCacheInternal, @@ -78,7 +84,7 @@ class NetworkMapUpdater(private val networkMapCache: NetworkMapCacheInternal, this.autoAcceptNetworkParameters = networkParameterAcceptanceSettings.autoAcceptEnabled this.excludedAutoAcceptNetworkParameters = networkParameterAcceptanceSettings.excludedAutoAcceptableParameters - val autoAcceptNetworkParametersNames = NetworkParameters.autoAcceptablePropertyNames - excludedAutoAcceptNetworkParameters + val autoAcceptNetworkParametersNames = autoAcceptablePropertyNames - excludedAutoAcceptNetworkParameters if (autoAcceptNetworkParameters && autoAcceptNetworkParametersNames.isNotEmpty()) { logger.info("Auto-accept enabled for network parameter changes which modify only: $autoAcceptNetworkParametersNames") } @@ -250,3 +256,27 @@ The node will shutdown now.""") } } } + +private val memberPropertyPartition = NetworkParameters::class.declaredMemberProperties.partition { it.isAutoAcceptable() } +private val autoAcceptableNamesAndGetters = memberPropertyPartition.first.associateBy({ it.name }, { it.javaGetter }) +@VisibleForTesting +internal val autoAcceptablePropertyNames = autoAcceptableNamesAndGetters.keys +private val nonAutoAcceptableGetters = memberPropertyPartition.second.map { it.javaGetter } + +/** + * Returns true if the only properties changed in [newNetworkParameters] are [AutoAcceptable] and not + * included in the [excludedParameterNames] + */ +@VisibleForTesting +internal fun NetworkParameters.canAutoAccept(newNetworkParameters: NetworkParameters, excludedParameterNames: Set): Boolean { + return nonAutoAcceptableGetters.none { valueChanged(newNetworkParameters, it) } && + autoAcceptableNamesAndGetters.none { it.key in excludedParameterNames && valueChanged(newNetworkParameters, it.value) } +} + +private fun KProperty1.isAutoAcceptable(): Boolean = findAnnotation() != null + +private fun NetworkParameters.valueChanged(newNetworkParameters: NetworkParameters, getter: Method?): Boolean { + val propertyValue = getter?.invoke(this) + val newPropertyValue = getter?.invoke(newNetworkParameters) + return propertyValue != newPropertyValue +} \ No newline at end of file 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 1e1a5722b1..f70ca0fc18 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 @@ -5,6 +5,7 @@ import com.google.common.jimfs.Jimfs import com.nhaarman.mockito_kotlin.* import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash +import net.corda.core.crypto.generateKeyPair import net.corda.core.crypto.sign import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party @@ -13,17 +14,20 @@ import net.corda.core.internal.concurrent.openFuture import net.corda.core.messaging.ParametersUpdateInfo import net.corda.core.node.NetworkParameters import net.corda.core.node.NodeInfo +import net.corda.core.node.services.AttachmentId import net.corda.core.serialization.serialize import net.corda.core.utilities.millis import net.corda.node.VersionInfo +import net.corda.node.internal.NetworkParametersStorageInternal import net.corda.node.services.api.NetworkMapCacheInternal import net.corda.node.services.config.NetworkParameterAcceptanceSettings -import net.corda.core.internal.NODE_INFO_DIRECTORY -import net.corda.node.internal.NetworkParametersStorageInternal import net.corda.nodeapi.internal.NodeInfoAndSigned import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.crypto.X509Utilities -import net.corda.nodeapi.internal.network.* +import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME +import net.corda.nodeapi.internal.network.NodeInfoFilesCopier +import net.corda.nodeapi.internal.network.SignedNetworkParameters +import net.corda.nodeapi.internal.network.verifiedNetworkParametersCert import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.core.* import net.corda.testing.internal.DEV_ROOT_CA @@ -48,6 +52,8 @@ import java.util.* import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.TimeUnit import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue class NetworkMapUpdaterTest { @Rule @@ -68,7 +74,7 @@ class NetworkMapUpdaterTest { private val networkParametersStorage: NetworkParametersStorageInternal = mock() private lateinit var server: NetworkMapServer private lateinit var networkMapClient: NetworkMapClient - private lateinit var updater: NetworkMapUpdater + private var updater: NetworkMapUpdater? = null @Before fun setUp() { @@ -82,7 +88,7 @@ class NetworkMapUpdaterTest { @After fun cleanUp() { - updater.close() + updater?.close() fs.close() server.close() } @@ -95,7 +101,7 @@ class NetworkMapUpdaterTest { networkParameters: NetworkParameters = server.networkParameters, autoAcceptNetworkParameters: Boolean = true, excludedAutoAcceptNetworkParameters: Set = emptySet()) { - updater.start(DEV_ROOT_CA.certificate, + updater!!.start(DEV_ROOT_CA.certificate, server.networkParameters.serialize().hash, ourNodeInfo, networkParameters, @@ -206,7 +212,7 @@ class NetworkMapUpdaterTest { @Test fun `emit new parameters update info on parameters update from network map`() { setUpdater() - val paramsFeed = updater.trackParametersUpdate() + val paramsFeed = updater!!.trackParametersUpdate() val snapshot = paramsFeed.snapshot val updates = paramsFeed.updates.bufferUntilSubscribed() assertEquals(null, snapshot) @@ -237,7 +243,7 @@ class NetworkMapUpdaterTest { val newHash = newParameters.serialize().hash val updateFile = baseDir / NETWORK_PARAMS_UPDATE_FILE_NAME assert(!updateFile.exists()) { "network parameters should not be auto accepted" } - updater.acceptNewNetworkParameters(newHash) { it.serialize().sign(ourKeyPair) } + updater!!.acceptNewNetworkParameters(newHash) { it.serialize().sign(ourKeyPair) } verify(networkParametersStorage, times(1)).saveParameters(any()) val signedNetworkParams = updateFile.readObject() val paramsFromFile = signedNetworkParams.verifiedNetworkParametersCert(DEV_ROOT_CA.certificate) @@ -411,6 +417,32 @@ class NetworkMapUpdaterTest { assert(networkMapCache.allNodeHashes.size == 1) } + @Test + fun `auto acceptance checks are correct`() { + val packageOwnership = mapOf( + "com.example1" to generateKeyPair().public, + "com.example2" to generateKeyPair().public + ) + val whitelistedContractImplementations = mapOf( + "example1" to listOf(AttachmentId.randomSHA256()), + "example2" to listOf(AttachmentId.randomSHA256()) + ) + + val netParams = testNetworkParameters() + val netParamsAutoAcceptable = netParams.copy( + packageOwnership = packageOwnership, + whitelistedContractImplementations = whitelistedContractImplementations + ) + val netParamsNotAutoAcceptable = netParamsAutoAcceptable.copy(maxMessageSize = netParams.maxMessageSize + 1) + + assertTrue(netParams.canAutoAccept(netParams, emptySet()), "auto-acceptable if identical") + assertTrue(netParams.canAutoAccept(netParams, autoAcceptablePropertyNames), "auto acceptable if identical regardless of exclusions") + assertTrue(netParams.canAutoAccept(netParamsAutoAcceptable, emptySet()), "auto-acceptable if only AutoAcceptable params have changed") + assertTrue(netParams.canAutoAccept(netParamsAutoAcceptable, setOf("modifiedTime")), "auto-acceptable if only AutoAcceptable params have changed and excluded param has not changed") + assertFalse(netParams.canAutoAccept(netParamsNotAutoAcceptable, emptySet()), "not auto-acceptable if non-AutoAcceptable param has changed") + assertFalse(netParams.canAutoAccept(netParamsAutoAcceptable, setOf("whitelistedContractImplementations")), "not auto-acceptable if only AutoAcceptable params have changed but one has been added to the exclusion set") + } + private fun createMockNetworkMapCache(): NetworkMapCacheInternal { return mock { on { nodeReady }.thenReturn(nodeReadyFuture) diff --git a/tools/bootstrapper/src/main/kotlin/net/corda/bootstrapper/NetworkParameterOverridesSpec.kt b/tools/bootstrapper/src/main/kotlin/net/corda/bootstrapper/NetworkParameterOverridesSpec.kt index ca98d8254f..03f8a1ee3f 100644 --- a/tools/bootstrapper/src/main/kotlin/net/corda/bootstrapper/NetworkParameterOverridesSpec.kt +++ b/tools/bootstrapper/src/main/kotlin/net/corda/bootstrapper/NetworkParameterOverridesSpec.kt @@ -6,9 +6,8 @@ import net.corda.common.configuration.parsing.internal.get import net.corda.common.configuration.parsing.internal.mapValid import net.corda.common.configuration.parsing.internal.nested import net.corda.common.validation.internal.Validated -import net.corda.core.internal.div +import net.corda.core.internal.noPackageOverlap import net.corda.core.internal.requirePackageValid -import net.corda.core.node.NetworkParameters import net.corda.nodeapi.internal.crypto.loadKeyStore import net.corda.nodeapi.internal.network.NetworkParametersOverrides import net.corda.nodeapi.internal.network.PackageOwner @@ -84,8 +83,12 @@ internal object NetworkParameterOverridesSpec : Configuration.Specification { val packageOwnership = configuration[packageOwnership] - if (packageOwnership != null && !NetworkParameters.noOverlap(packageOwnership.map { it.javaPackageName })) { - return Validated.invalid(sequenceOf(Configuration.Validation.Error.BadValue.of("Package namespaces must not overlap", keyName = "packageOwnership", containingPath = listOf())).toSet()) + if (packageOwnership != null && !noPackageOverlap(packageOwnership.map { it.javaPackageName })) { + return Validated.invalid(sequenceOf(Configuration.Validation.Error.BadValue.of( + "Package namespaces must not overlap", + keyName = "packageOwnership", + containingPath = listOf() + )).toSet()) } return valid(NetworkParametersOverrides( minimumPlatformVersion = configuration[minimumPlatformVersion],