From 4362ef663795c33242a95c3ced5454eb81c4163d Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Fri, 14 Jan 2022 11:35:11 +0000 Subject: [PATCH 01/28] ENT-6426: update docker tahhing inline with our policies old corda/corda-zulu-java1.8-4.8.5:latest new corda/corda:4.8.5-zulu-1.8 based on pattern {repo}:{version}-{base-Image} --- docker/build.gradle | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/docker/build.gradle b/docker/build.gradle index 394826e3a7..535dd4562c 100644 --- a/docker/build.gradle +++ b/docker/build.gradle @@ -42,12 +42,6 @@ enum ImageVariant { String dockerFile String javaVersion - String versionString(String baseTag, String version) { - return "${baseTag}-${knownAs}" + - (knownAs.isEmpty() ? "" : "-") + - "java${javaVersion}-" + version - } - ImageVariant(ImageVariant other) { this.knownAs = other.knownAs this.dockerFile = other.dockerFile @@ -64,16 +58,9 @@ enum ImageVariant { return project.properties.getOrDefault("docker.image.repository", "corda/corda") } - static private final String runTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) - - def getName(Project project) { - return versionString(getRepository(project), project.version.toString().toLowerCase()) - } - Set buildTags(Project project) { - final String suffix = project.version.toString().toLowerCase().contains("snapshot") ? runTime : "RELEASE" - return [suffix, "latest"].stream().map { - toAppend -> "${getName(project)}:${toAppend}".toString() + return ["${project.version.toString().toLowerCase()}-${knownAs}-${javaVersion}"].stream().map { + toAppend -> "${getRepository(project)}:${toAppend}".toString() }.map(Identifier.&fromCompoundString).collect(Collectors.toSet()) } From ccbfb0462cb74258d5d82884650ed937cf1adb93 Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Sun, 16 Jan 2022 17:01:23 +0000 Subject: [PATCH 02/28] ENT-6426: update docker tahhing inline with our policies old corda/corda-zulu-java1.8-4.8.5:latest new corda/corda:4.8.5-zulu-openjdk8 based on pattern {repo}:{version}-{base-Image} Remove some redundant code --- docker/build.gradle | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docker/build.gradle b/docker/build.gradle index 535dd4562c..09fb2ba8e6 100644 --- a/docker/build.gradle +++ b/docker/build.gradle @@ -33,25 +33,25 @@ shadowJar { } enum ImageVariant { - UBUNTU_ZULU("zulu", "Dockerfile", "1.8"), - UBUNTU_ZULU_11("zulu", "Dockerfile11", "11"), - AL_CORRETTO("corretto", "DockerfileAL", "1.8"), + UBUNTU_ZULU("Dockerfile", "1.8", "zulu-openjdk8"), + UBUNTU_ZULU_11("Dockerfile11", "11", "zulu-openjdk11"), + AL_CORRETTO("DockerfileAL", "1.8", "amazonlinux2"), OFFICIAL(UBUNTU_ZULU) - String knownAs String dockerFile String javaVersion + String baseImgaeFullName ImageVariant(ImageVariant other) { - this.knownAs = other.knownAs this.dockerFile = other.dockerFile this.javaVersion = other.javaVersion + this.baseImgaeFullName = other.baseImgaeFullName } - ImageVariant(String knownAs, String dockerFile, String javaVersion) { - this.knownAs = knownAs + ImageVariant(String dockerFile, String javaVersion, String baseImgaeFullName) { this.dockerFile = dockerFile this.javaVersion = javaVersion + this.baseImgaeFullName = baseImgaeFullName } static final String getRepository(Project project) { @@ -59,7 +59,7 @@ enum ImageVariant { } Set buildTags(Project project) { - return ["${project.version.toString().toLowerCase()}-${knownAs}-${javaVersion}"].stream().map { + return ["${project.version.toString().toLowerCase()}-${baseImgaeFullName}"].stream().map { toAppend -> "${getRepository(project)}:${toAppend}".toString() }.map(Identifier.&fromCompoundString).collect(Collectors.toSet()) } From e15bd0692f4aa37fa99f60e355b97f856fd6ca8d Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Mon, 17 Jan 2022 12:40:43 +0000 Subject: [PATCH 03/28] ENT-6426 update corda repo tagging --- .ci/dev/regression/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 96abe97cfa..6289a4e362 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -317,7 +317,7 @@ pipeline { './gradlew', COMMON_GRADLE_PARAMS, 'docker:pushDockerImage', - '-Pdocker.image.repository=corda/corda', + '-Pdocker.image.repository=corda/community-node', '--image OFFICIAL' ].join(' ') } From a45be650c7ae3e929305032527cd800e8397657c Mon Sep 17 00:00:00 2001 From: Ramzi El-Yafi Date: Thu, 20 Jan 2022 09:52:45 +0000 Subject: [PATCH 04/28] ENT-6533 Update validating notary flow to be non-idempotent (#7031) --- .../net/corda/core/internal/notary/NotaryServiceFlow.kt | 3 +-- .../node/services/transactions/NonValidatingNotaryFlow.kt | 6 +++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/internal/notary/NotaryServiceFlow.kt b/core/src/main/kotlin/net/corda/core/internal/notary/NotaryServiceFlow.kt index b5bc562844..eefc7796cb 100644 --- a/core/src/main/kotlin/net/corda/core/internal/notary/NotaryServiceFlow.kt +++ b/core/src/main/kotlin/net/corda/core/internal/notary/NotaryServiceFlow.kt @@ -7,7 +7,6 @@ import net.corda.core.crypto.SecureHash import net.corda.core.crypto.TransactionSignature import net.corda.core.flows.* import net.corda.core.identity.Party -import net.corda.core.internal.IdempotentFlow import net.corda.core.internal.MIN_PLATFORM_VERSION_FOR_BACKPRESSURE_MESSAGE import net.corda.core.internal.checkParameterHash import net.corda.core.utilities.seconds @@ -28,7 +27,7 @@ import java.time.Duration * @param etaThreshold If the ETA for processing the request, according to the service, is greater than this, notify the client. */ // See AbstractStateReplacementFlow.Acceptor for why it's Void? -abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service: SinglePartyNotaryService, private val etaThreshold: Duration) : FlowLogic(), IdempotentFlow { +abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service: SinglePartyNotaryService, private val etaThreshold: Duration) : FlowLogic() { companion object { // TODO: Determine an appropriate limit and also enforce in the network parameters and the transaction builder. private const val maxAllowedInputsAndReferences = 10_000 diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt b/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt index 6d34720b2f..74290412a3 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt @@ -6,6 +6,7 @@ import net.corda.core.flows.FlowSession import net.corda.core.flows.NotarisationPayload import net.corda.core.flows.NotaryError import net.corda.core.identity.Party +import net.corda.core.internal.IdempotentFlow import net.corda.core.internal.notary.NotaryInternalException import net.corda.core.internal.notary.NotaryServiceFlow import net.corda.core.internal.notary.SinglePartyNotaryService @@ -24,7 +25,10 @@ import java.time.Duration * the caller, it is possible to raise a dispute and verify the validity of the transaction and subsequently * undo the commit of the input states (the exact mechanism still needs to be worked out). */ -class NonValidatingNotaryFlow(otherSideSession: FlowSession, service: SinglePartyNotaryService, etaThreshold: Duration) : NotaryServiceFlow(otherSideSession, service, etaThreshold) { +class NonValidatingNotaryFlow(otherSideSession: FlowSession, service: SinglePartyNotaryService, etaThreshold: Duration) : + NotaryServiceFlow(otherSideSession, service, etaThreshold), + IdempotentFlow +{ private val minPlatformVersion get() = serviceHub.networkParameters.minimumPlatformVersion override fun extractParts(requestPayload: NotarisationPayload): TransactionParts { From 9454aa605e661994f08a7ac1535a39c850e56912 Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Tue, 25 Jan 2022 17:39:31 +0000 Subject: [PATCH 05/28] ENT-6426 update corda repo tagging --- .ci/dev/regression/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 6289a4e362..96abe97cfa 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -317,7 +317,7 @@ pipeline { './gradlew', COMMON_GRADLE_PARAMS, 'docker:pushDockerImage', - '-Pdocker.image.repository=corda/community-node', + '-Pdocker.image.repository=corda/corda', '--image OFFICIAL' ].join(' ') } From c11eb382ce364ae5d8ecd0df575276a8d6c550ac Mon Sep 17 00:00:00 2001 From: Adel El-Beik <48713346+adelel1@users.noreply.github.com> Date: Fri, 18 Feb 2022 09:42:59 +0000 Subject: [PATCH 06/28] ENT-6588 Restrict database operations platform flag (#7053) (#7073) (#7074) (#7076) * ENT-6588 Restrict database operations platform flag Put the restricting of database operations in `RestrictedConnection` and `RestrictedEntityManager` behind a platform version flag. `RESTRICTED_DATABASE_OPERATIONS = 7` was added to signify this. If the version is less than 7, then the database operations will not be restricted. A warning is logged to indicate that they are using potentially dangerous methods. If the version is 7 or greater, then the database operations are restricted and throw an error if called. Co-authored-by: Dan Newton --- .../core/internal/PlatformVersionSwitches.kt | 1 + .../RestrictedConnectionFlowTest.kt | 52 ++- .../RestrictedEntityManagerFlowTest.kt | 58 +++- .../persistence/RestrictedConnection.kt | 41 +-- .../RestrictedDatabaseOperations.kt | 31 ++ .../persistence/RestrictedEntityManager.kt | 32 +- .../persistence/RestrictedConnectionTest.kt | 311 +++++++++++++++--- .../RestrictedEntityManagerTest.kt | 153 ++++++++- .../net/corda/node/internal/AbstractNode.kt | 4 +- 9 files changed, 559 insertions(+), 124 deletions(-) create mode 100644 node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedDatabaseOperations.kt diff --git a/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt b/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt index 4370f998b9..3628c05526 100644 --- a/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt +++ b/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt @@ -17,4 +17,5 @@ object PlatformVersionSwitches { const val BATCH_DOWNLOAD_COUNTERPARTY_BACKCHAIN = 6 const val ENABLE_P2P_COMPRESSION = 7 const val CERTIFICATE_ROTATION = 9 + const val RESTRICTED_DATABASE_OPERATIONS = 7 } \ No newline at end of file diff --git a/node-api-tests/src/test/kotlin/net/corda/nodeapitests/internal/persistence/RestrictedConnectionFlowTest.kt b/node-api-tests/src/test/kotlin/net/corda/nodeapitests/internal/persistence/RestrictedConnectionFlowTest.kt index f948c75f37..e00e65ec44 100644 --- a/node-api-tests/src/test/kotlin/net/corda/nodeapitests/internal/persistence/RestrictedConnectionFlowTest.kt +++ b/node-api-tests/src/test/kotlin/net/corda/nodeapitests/internal/persistence/RestrictedConnectionFlowTest.kt @@ -4,14 +4,15 @@ import co.paralleluniverse.fibers.Suspendable import net.corda.core.flows.FlowLogic import net.corda.core.flows.InitiatingFlow import net.corda.core.identity.CordaX500Name +import net.corda.core.internal.PLATFORM_VERSION import net.corda.core.utilities.getOrThrow import net.corda.nodeapi.internal.persistence.RestrictedConnection import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetworkParameters import net.corda.testing.node.StartedMockNode +import net.corda.testing.node.internal.enclosedCordapp import org.assertj.core.api.Assertions import org.junit.After -import org.junit.Before import org.junit.Test import kotlin.test.assertTrue @@ -38,40 +39,63 @@ class RestrictedConnectionFlowTest { } @InitiatingFlow - class TestCloseMethodIsBlocked : FlowLogic() { + class TestClearWarningsMethodIsBlocked : FlowLogic() { @Suspendable override fun call() { val connection = serviceHub.jdbcSession() - connection.close() + connection.clearWarnings() } } - @Before - fun init() { - mockNetwork = MockNetwork(MockNetworkParameters()) - aliceNode = mockNetwork.createPartyNode(CordaX500Name("Alice", "London", "GB")) - } - @After fun done() { mockNetwork.stopNodes() } @Test(timeout=300_000) - fun testIfItIsRestrictedConnection() { + fun `restricted connection is returned from ServiceHub#jdbcSession`() { + mockNetwork = MockNetwork(MockNetworkParameters(listOf(enclosedCordapp().copy(targetPlatformVersion = PLATFORM_VERSION)))) + aliceNode = mockNetwork.createPartyNode(CordaX500Name("Alice", "London", "GB")) assertTrue { aliceNode.startFlow(TestIfItIsRestrictedConnection()).get() } mockNetwork.runNetwork() } @Test(timeout=300_000) - fun testMethodsAreBlocked() { + fun `restricted methods are blocked when the target platform is the current corda version`() { + mockNetwork = MockNetwork(MockNetworkParameters(listOf(enclosedCordapp().copy(targetPlatformVersion = PLATFORM_VERSION)))) + aliceNode = mockNetwork.createPartyNode(CordaX500Name("Alice", "London", "GB")) Assertions.assertThatExceptionOfType(UnsupportedOperationException::class.java) .isThrownBy { aliceNode.startFlow(TestAutoCommitMethodIsBlocked()).getOrThrow() } - .withMessageContaining("This method cannot be called via ServiceHub.jdbcSession.") + .withMessageContaining("ServiceHub.jdbcSession.setAutoCommit is restricted and cannot be called") Assertions.assertThatExceptionOfType(UnsupportedOperationException::class.java) - .isThrownBy { aliceNode.startFlow(TestCloseMethodIsBlocked()).getOrThrow() } - .withMessageContaining("This method cannot be called via ServiceHub.jdbcSession.") + .isThrownBy { aliceNode.startFlow(TestClearWarningsMethodIsBlocked()).getOrThrow() } + .withMessageContaining("ServiceHub.jdbcSession.clearWarnings is restricted and cannot be called") + + mockNetwork.runNetwork() + } + + @Test(timeout=300_000) + fun `restricted methods are blocked when the target platform is 7`() { + mockNetwork = MockNetwork(MockNetworkParameters(listOf(enclosedCordapp().copy(targetPlatformVersion = 7)))) + aliceNode = mockNetwork.createPartyNode(CordaX500Name("Alice", "London", "GB")) + Assertions.assertThatExceptionOfType(UnsupportedOperationException::class.java) + .isThrownBy { aliceNode.startFlow(TestAutoCommitMethodIsBlocked()).getOrThrow() } + .withMessageContaining("ServiceHub.jdbcSession.setAutoCommit is restricted and cannot be called") + + Assertions.assertThatExceptionOfType(UnsupportedOperationException::class.java) + .isThrownBy { aliceNode.startFlow(TestClearWarningsMethodIsBlocked()).getOrThrow() } + .withMessageContaining("ServiceHub.jdbcSession.clearWarnings is restricted and cannot be called") + + mockNetwork.runNetwork() + } + + @Test(timeout=300_000) + fun `restricted methods are not blocked when the target platform is 6`() { + mockNetwork = MockNetwork(MockNetworkParameters(listOf(enclosedCordapp().copy(targetPlatformVersion = 6)))) + aliceNode = mockNetwork.createPartyNode(CordaX500Name("Alice", "London", "GB")) + aliceNode.startFlow(TestAutoCommitMethodIsBlocked()).getOrThrow() + aliceNode.startFlow(TestClearWarningsMethodIsBlocked()).getOrThrow() mockNetwork.runNetwork() } diff --git a/node-api-tests/src/test/kotlin/net/corda/nodeapitests/internal/persistence/RestrictedEntityManagerFlowTest.kt b/node-api-tests/src/test/kotlin/net/corda/nodeapitests/internal/persistence/RestrictedEntityManagerFlowTest.kt index 7da2ff26ff..995440973d 100644 --- a/node-api-tests/src/test/kotlin/net/corda/nodeapitests/internal/persistence/RestrictedEntityManagerFlowTest.kt +++ b/node-api-tests/src/test/kotlin/net/corda/nodeapitests/internal/persistence/RestrictedEntityManagerFlowTest.kt @@ -4,14 +4,15 @@ import co.paralleluniverse.fibers.Suspendable import net.corda.core.flows.FlowLogic import net.corda.core.flows.InitiatingFlow import net.corda.core.identity.CordaX500Name +import net.corda.core.internal.PLATFORM_VERSION import net.corda.core.utilities.getOrThrow import net.corda.nodeapi.internal.persistence.RestrictedEntityManager import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetworkParameters import net.corda.testing.node.StartedMockNode +import net.corda.testing.node.internal.enclosedCordapp import org.assertj.core.api.Assertions import org.junit.After -import org.junit.Before import org.junit.Test import kotlin.test.assertTrue @@ -25,7 +26,7 @@ class RestrictedEntityManagerFlowTest { @Suspendable override fun call() : Boolean { var result = false - serviceHub.withEntityManager() { + serviceHub.withEntityManager { result = this is RestrictedEntityManager } return result @@ -33,11 +34,11 @@ class RestrictedEntityManagerFlowTest { } @InitiatingFlow - class TestCloseMethodIsBlocked : FlowLogic() { + class TestGetMetamodelMethodIsBlocked : FlowLogic() { @Suspendable override fun call() { - serviceHub.withEntityManager() { - this.close() + serviceHub.withEntityManager { + this.metamodel } } } @@ -46,38 +47,61 @@ class RestrictedEntityManagerFlowTest { class TestJoinTransactionMethodIsBlocked : FlowLogic() { @Suspendable override fun call() { - serviceHub.withEntityManager() { + serviceHub.withEntityManager { this.joinTransaction() } } } - @Before - fun init() { - mockNetwork = MockNetwork(MockNetworkParameters()) - aliceNode = mockNetwork.createPartyNode(CordaX500Name("Alice", "London", "GB")) - } - @After fun done() { mockNetwork.stopNodes() } @Test(timeout=300_000) - fun testIfItIsRestrictedConnection() { + fun `restricted connection is returned from ServiceHub#withEntityManager`() { + mockNetwork = MockNetwork(MockNetworkParameters(listOf(enclosedCordapp().copy(targetPlatformVersion = PLATFORM_VERSION)))) + aliceNode = mockNetwork.createPartyNode(CordaX500Name("Alice", "London", "GB")) assertTrue { aliceNode.startFlow(TestIfItIsRestrictedEntityManager()).get() } mockNetwork.runNetwork() } @Test(timeout=300_000) - fun testMethodsAreBlocked() { + fun `restricted methods are blocked when the target platform is the current corda version`() { + mockNetwork = MockNetwork(MockNetworkParameters(listOf(enclosedCordapp().copy(targetPlatformVersion = PLATFORM_VERSION)))) + aliceNode = mockNetwork.createPartyNode(CordaX500Name("Alice", "London", "GB")) Assertions.assertThatExceptionOfType(UnsupportedOperationException::class.java) - .isThrownBy { aliceNode.startFlow(TestCloseMethodIsBlocked()).getOrThrow() } - .withMessageContaining("This method cannot be called via ServiceHub.withEntityManager.") + .isThrownBy { aliceNode.startFlow(TestGetMetamodelMethodIsBlocked()).getOrThrow() } + .withMessageContaining("ServiceHub.withEntityManager.getMetamodel is restricted and cannot be called") Assertions.assertThatExceptionOfType(UnsupportedOperationException::class.java) .isThrownBy { aliceNode.startFlow(TestJoinTransactionMethodIsBlocked()).getOrThrow() } - .withMessageContaining("This method cannot be called via ServiceHub.withEntityManager.") + .withMessageContaining("ServiceHub.withEntityManager.joinTransaction is restricted and cannot be called") + + mockNetwork.runNetwork() + } + + @Test(timeout=300_000) + fun `restricted methods are blocked when the target platform is 7`() { + mockNetwork = MockNetwork(MockNetworkParameters(listOf(enclosedCordapp().copy(targetPlatformVersion = 7)))) + aliceNode = mockNetwork.createPartyNode(CordaX500Name("Alice", "London", "GB")) + Assertions.assertThatExceptionOfType(UnsupportedOperationException::class.java) + .isThrownBy { aliceNode.startFlow(TestGetMetamodelMethodIsBlocked()).getOrThrow() } + .withMessageContaining("ServiceHub.withEntityManager.getMetamodel is restricted and cannot be called") + + Assertions.assertThatExceptionOfType(UnsupportedOperationException::class.java) + .isThrownBy { aliceNode.startFlow(TestJoinTransactionMethodIsBlocked()).getOrThrow() } + .withMessageContaining("ServiceHub.withEntityManager.joinTransaction is restricted and cannot be called") + + mockNetwork.runNetwork() + } + + @Test(timeout=300_000) + fun `restricted methods are not blocked when the target platform is 6`() { + mockNetwork = MockNetwork(MockNetworkParameters(listOf(enclosedCordapp().copy(targetPlatformVersion = 6)))) + aliceNode = mockNetwork.createPartyNode(CordaX500Name("Alice", "London", "GB")) + aliceNode.startFlow(TestGetMetamodelMethodIsBlocked()).getOrThrow() + aliceNode.startFlow(TestJoinTransactionMethodIsBlocked()).getOrThrow() mockNetwork.runNetwork() } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedConnection.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedConnection.kt index 997cdc3ebd..a2a471c364 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedConnection.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedConnection.kt @@ -1,5 +1,6 @@ package net.corda.nodeapi.internal.persistence +import net.corda.core.node.ServiceHub import java.sql.Connection import java.sql.Savepoint import java.util.concurrent.Executor @@ -8,73 +9,73 @@ import java.util.concurrent.Executor * A delegate of [Connection] which disallows some operations. */ @Suppress("TooManyFunctions") -class RestrictedConnection(private val delegate : Connection) : Connection by delegate { +class RestrictedConnection(private val delegate: Connection, private val serviceHub: ServiceHub) : Connection by delegate { override fun abort(executor: Executor?) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("abort", serviceHub) { delegate.abort(executor) } } override fun clearWarnings() { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("clearWarnings", serviceHub) { delegate.clearWarnings() } } override fun close() { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("close", serviceHub) { delegate.close() } } override fun commit() { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("commit", serviceHub) { delegate.commit() } } override fun setSavepoint(): Savepoint? { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + return restrictDatabaseOperationFromJdbcSession("setSavepoint", serviceHub) { delegate.setSavepoint() } } - override fun setSavepoint(name : String?): Savepoint? { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + override fun setSavepoint(name: String?): Savepoint? { + return restrictDatabaseOperationFromJdbcSession("setSavepoint", serviceHub) { delegate.setSavepoint(name) } } override fun releaseSavepoint(savepoint: Savepoint?) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("releaseSavepoint", serviceHub) { delegate.releaseSavepoint(savepoint) } } override fun rollback() { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("rollback", serviceHub) { delegate.rollback() } } override fun rollback(savepoint: Savepoint?) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("rollback", serviceHub) { delegate.rollback(savepoint) } } - override fun setCatalog(catalog : String?) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + override fun setCatalog(catalog: String?) { + restrictDatabaseOperationFromJdbcSession("setCatalog", serviceHub) { delegate.catalog = catalog } } override fun setTransactionIsolation(level: Int) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("setTransactionIsolation", serviceHub) { delegate.transactionIsolation = level } } override fun setTypeMap(map: MutableMap>?) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("setTypeMap", serviceHub) { delegate.typeMap = map } } override fun setHoldability(holdability: Int) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("setHoldability", serviceHub) { delegate.holdability = holdability } } override fun setSchema(schema: String?) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("setSchema", serviceHub) { delegate.schema = schema } } override fun setNetworkTimeout(executor: Executor?, milliseconds: Int) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("setNetworkTimeout", serviceHub) { delegate.setNetworkTimeout(executor, milliseconds) } } override fun setAutoCommit(autoCommit: Boolean) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("setAutoCommit", serviceHub) { delegate.autoCommit = autoCommit } } override fun setReadOnly(readOnly: Boolean) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.") + restrictDatabaseOperationFromJdbcSession("setReadOnly", serviceHub) { delegate.isReadOnly = readOnly } } } \ No newline at end of file diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedDatabaseOperations.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedDatabaseOperations.kt new file mode 100644 index 0000000000..bc5cbc055f --- /dev/null +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedDatabaseOperations.kt @@ -0,0 +1,31 @@ +package net.corda.nodeapi.internal.persistence + +import net.corda.core.internal.PlatformVersionSwitches.RESTRICTED_DATABASE_OPERATIONS +import net.corda.core.internal.warnOnce +import net.corda.core.node.ServiceHub +import org.slf4j.LoggerFactory + +private val log = LoggerFactory.getLogger("RestrictedDatabaseOperations") + +internal inline fun restrictDatabaseOperationFromJdbcSession(method: String, serviceHub: ServiceHub, operation: () -> T): T { + return restrictDatabaseOperation("ServiceHub.jdbcSession.$method", serviceHub, operation) +} + +internal inline fun restrictDatabaseOperationFromEntityManager(method: String, serviceHub: ServiceHub, operation: () -> T): T { + return restrictDatabaseOperation("ServiceHub.withEntityManager.$method", serviceHub, operation) +} + +internal inline fun restrictDatabaseOperation(method: String, serviceHub: ServiceHub, operation: () -> T): T { + return if (serviceHub.getAppContext().cordapp.targetPlatformVersion >= RESTRICTED_DATABASE_OPERATIONS) { + throw UnsupportedOperationException("$method is restricted and cannot be called") + } else { + log.warnOnce( + "$method should not be called, as manipulating database transactions and connections breaks the Corda flow state machine in " + + "ways that only become evident in failure scenarios. Purely for API backwards compatibility reasons, the prior " + + "behaviour is continued for target platform versions less than $RESTRICTED_DATABASE_OPERATIONS. You should evolve " + + "the CorDapp away from using these problematic APIs as soon as possible. For target platform version of " + + "$RESTRICTED_DATABASE_OPERATIONS or above, an exception will be thrown instead." + ) + operation() + } +} \ No newline at end of file diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedEntityManager.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedEntityManager.kt index 1ea4f2c4fd..d6d2672c0d 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedEntityManager.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/RestrictedEntityManager.kt @@ -1,5 +1,6 @@ package net.corda.nodeapi.internal.persistence +import net.corda.core.node.ServiceHub import javax.persistence.EntityManager import javax.persistence.EntityTransaction import javax.persistence.LockModeType @@ -8,56 +9,59 @@ import javax.persistence.metamodel.Metamodel /** * A delegate of [EntityManager] which disallows some operations. */ -class RestrictedEntityManager(private val delegate: EntityManager) : EntityManager by delegate { +class RestrictedEntityManager(private val delegate: EntityManager, private val serviceHub: ServiceHub) : EntityManager by delegate { override fun getTransaction(): EntityTransaction { - return RestrictedEntityTransaction(delegate.transaction) + return RestrictedEntityTransaction(delegate.transaction, serviceHub) } override fun close() { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + restrictDatabaseOperationFromEntityManager("close", serviceHub) { delegate.close() } } override fun unwrap(cls: Class?): T { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + return restrictDatabaseOperationFromEntityManager("unwrap", serviceHub) { delegate.unwrap(cls) } } override fun getDelegate(): Any { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + return restrictDatabaseOperationFromEntityManager("getDelegate", serviceHub) { delegate.delegate } } override fun getMetamodel(): Metamodel? { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + return restrictDatabaseOperationFromEntityManager("getMetamodel", serviceHub) { delegate.metamodel } } override fun joinTransaction() { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + restrictDatabaseOperationFromEntityManager("joinTransaction", serviceHub) { delegate.joinTransaction() } } override fun lock(entity: Any?, lockMode: LockModeType?) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + restrictDatabaseOperationFromEntityManager("lock", serviceHub) { delegate.lock(entity, lockMode) } } override fun lock(entity: Any?, lockMode: LockModeType?, properties: MutableMap?) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + restrictDatabaseOperationFromEntityManager("lock", serviceHub) { delegate.lock(entity, lockMode, properties) } } override fun setProperty(propertyName: String?, value: Any?) { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + restrictDatabaseOperationFromEntityManager("lock", serviceHub) { delegate.setProperty(propertyName, value) } } } -class RestrictedEntityTransaction(private val delegate: EntityTransaction) : EntityTransaction by delegate { +class RestrictedEntityTransaction( + private val delegate: EntityTransaction, + private val serviceHub: ServiceHub +) : EntityTransaction by delegate { override fun rollback() { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + restrictDatabaseOperationFromEntityManager("EntityTransaction.rollback", serviceHub) { delegate.rollback() } } override fun commit() { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + restrictDatabaseOperationFromEntityManager("EntityTransaction.commit", serviceHub) { delegate.commit() } } override fun begin() { - throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.") + restrictDatabaseOperationFromEntityManager("EntityTransaction.begin", serviceHub) { delegate.begin() } } } \ No newline at end of file diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/persistence/RestrictedConnectionTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/persistence/RestrictedConnectionTest.kt index 3708360bfc..39f2d7af73 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/persistence/RestrictedConnectionTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/persistence/RestrictedConnectionTest.kt @@ -1,104 +1,337 @@ package net.corda.nodeapi.internal.persistence import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.whenever +import net.corda.core.cordapp.Cordapp +import net.corda.core.cordapp.CordappContext +import net.corda.core.internal.PLATFORM_VERSION +import net.corda.core.node.ServiceHub import org.junit.Test import java.sql.Connection import java.sql.Savepoint class RestrictedConnectionTest { - private val connection : Connection = mock() - private val savePoint : Savepoint = mock() - private val restrictedConnection : RestrictedConnection = RestrictedConnection(connection) + private val connection: Connection = mock() + private val savePoint: Savepoint = mock() + private val cordapp = mock() + private val cordappContext = CordappContext.create(cordapp, null, javaClass.classLoader, mock()) + private val serviceHub = mock().apply { + whenever(getAppContext()).thenReturn(cordappContext) + } + private val restrictedConnection: RestrictedConnection = RestrictedConnection(connection, serviceHub) companion object { - private const val TEST_STRING : String = "test" - private const val TEST_INT : Int = 1 + private const val TEST_STRING: String = "test" + private const val TEST_INT: Int = 1 } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testAbort() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `abort with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.abort { println("I'm just an executor for this test...") } } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testClearWarnings() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `clearWarnings with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.clearWarnings() } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testClose() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `close with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.close() } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testCommit() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `commit with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.commit() } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetSavepoint() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setSavepoint with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.setSavepoint() } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetSavepointWithName() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setSavepoint with name with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.setSavepoint(TEST_STRING) } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testReleaseSavepoint() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `releaseSavepoint with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.releaseSavepoint(savePoint) } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testRollback() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `rollback with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.rollback() } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testRollbackWithSavepoint() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `rollbackWithSavepoint with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.rollback(savePoint) } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetCatalog() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setCatalog with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.catalog = TEST_STRING } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetTransactionIsolation() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setTransactionIsolation with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.transactionIsolation = TEST_INT } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetTypeMap() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setTypeMap with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) val map: MutableMap> = mutableMapOf() restrictedConnection.typeMap = map } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetHoldability() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setHoldability with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.holdability = TEST_INT } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetSchema() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setSchema with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.schema = TEST_STRING } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetNetworkTimeout() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setNetworkTimeout with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.setNetworkTimeout({ println("I'm just an executor for this test...") }, TEST_INT) } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetAutoCommit() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setAutoCommit with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedConnection.autoCommit = true } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetReadOnly() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setReadOnly with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) + restrictedConnection.isReadOnly = true + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `abort with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.abort { println("I'm just an executor for this test...") } + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `clearWarnings with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.clearWarnings() + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `close with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.close() + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `commit with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.commit() + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setSavepoint with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.setSavepoint() + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setSavepoint with name with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.setSavepoint(TEST_STRING) + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `releaseSavepoint with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.releaseSavepoint(savePoint) + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `rollback with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.rollback() + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `rollbackWithSavepoint with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.rollback(savePoint) + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setCatalog with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.catalog = TEST_STRING + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setTransactionIsolation with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.transactionIsolation = TEST_INT + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setTypeMap with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + val map: MutableMap> = mutableMapOf() + restrictedConnection.typeMap = map + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setHoldability with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.holdability = TEST_INT + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setSchema with target platform version of current 7 unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.schema = TEST_STRING + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setNetworkTimeout with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.setNetworkTimeout({ println("I'm just an executor for this test...") }, TEST_INT) + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setAutoCommit with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.autoCommit = true + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setReadOnly with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedConnection.isReadOnly = true + } + + @Test(timeout = 300_000) + fun `abort with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.abort { println("I'm just an executor for this test...") } + } + + @Test(timeout = 300_000) + fun `clearWarnings with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.clearWarnings() + } + + @Test(timeout = 300_000) + fun `close with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.close() + } + + @Test(timeout = 300_000) + fun `commit with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.commit() + } + + @Test(timeout = 300_000) + fun `setSavepoint with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.setSavepoint() + } + + @Test(timeout = 300_000) + fun `setSavepoint with name with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.setSavepoint(TEST_STRING) + } + + @Test(timeout = 300_000) + fun `releaseSavepoint with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.releaseSavepoint(savePoint) + } + + @Test(timeout = 300_000) + fun `rollback with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.rollback() + } + + @Test(timeout = 300_000) + fun `rollbackWithSavepoint with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.rollback(savePoint) + } + + @Test(timeout = 300_000) + fun `setCatalog with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.catalog = TEST_STRING + } + + @Test(timeout = 300_000) + fun `setTransactionIsolation with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.transactionIsolation = TEST_INT + } + + @Test(timeout = 300_000) + fun `setTypeMap with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + val map: MutableMap> = mutableMapOf() + restrictedConnection.typeMap = map + } + + @Test(timeout = 300_000) + fun `setHoldability with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.holdability = TEST_INT + } + + @Test(timeout = 300_000) + fun `setSchema with target platform version of current 6 unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.schema = TEST_STRING + } + + @Test(timeout = 300_000) + fun `setNetworkTimeout with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.setNetworkTimeout({ println("I'm just an executor for this test...") }, TEST_INT) + } + + @Test(timeout = 300_000) + fun `setAutoCommit with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedConnection.autoCommit = true + } + + @Test(timeout = 300_000) + fun `setReadOnly with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) restrictedConnection.isReadOnly = true } } \ No newline at end of file diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/persistence/RestrictedEntityManagerTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/persistence/RestrictedEntityManagerTest.kt index 6f53ade01c..92994a7fab 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/persistence/RestrictedEntityManagerTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/persistence/RestrictedEntityManagerTest.kt @@ -3,6 +3,10 @@ package net.corda.nodeapi.internal.persistence import com.nhaarman.mockito_kotlin.doReturn import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.whenever +import net.corda.core.cordapp.Cordapp +import net.corda.core.cordapp.CordappContext +import net.corda.core.internal.PLATFORM_VERSION +import net.corda.core.node.ServiceHub import org.junit.Test import javax.persistence.EntityManager import javax.persistence.EntityTransaction @@ -12,47 +16,160 @@ import kotlin.test.assertTrue class RestrictedEntityManagerTest { private val entitymanager = mock() private val transaction = mock() - private val restrictedEntityManager = RestrictedEntityManager(entitymanager) + private val cordapp = mock() + private val cordappContext = CordappContext.create(cordapp, null, javaClass.classLoader, mock()) + private val serviceHub = mock().apply { + whenever(getAppContext()).thenReturn(cordappContext) + } + private val restrictedEntityManager = RestrictedEntityManager(entitymanager, serviceHub) - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testClose() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `close with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedEntityManager.close() } @Test(timeout = 300_000) - fun testClear() { + fun `clear with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedEntityManager.clear() } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testGetMetaModel() { - restrictedEntityManager.getMetamodel() + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `getMetaModel with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) + restrictedEntityManager.metamodel } @Test(timeout = 300_000) - fun testGetTransaction() { + fun `getTransaction with target platform version of current corda version executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) whenever(entitymanager.transaction).doReturn(transaction) assertTrue(restrictedEntityManager.transaction is RestrictedEntityTransaction) } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testJoinTransaction() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `joinTransaction with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedEntityManager.joinTransaction() } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testLockWithTwoParameters() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `lock with two parameters with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC) } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testLockWithThreeParameters() { - val map: MutableMap = mutableMapOf() - restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC,map) + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `lock with three parameters with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) + val map: MutableMap = mutableMapOf() + restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC, map) } - @Test(expected = UnsupportedOperationException::class, timeout=300_000) - fun testSetProperty() { + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setProperty with target platform version of current corda version throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION) + restrictedEntityManager.setProperty("number", 12) + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `close with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedEntityManager.close() + } + + @Test(timeout = 300_000) + fun `clear with target platform version of 7 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedEntityManager.clear() + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `getMetaModel with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedEntityManager.metamodel + } + + @Test(timeout = 300_000) + fun `getTransaction with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + whenever(entitymanager.transaction).doReturn(transaction) + assertTrue(restrictedEntityManager.transaction is RestrictedEntityTransaction) + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `joinTransaction with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedEntityManager.joinTransaction() + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `lock with two parameters with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC) + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `lock with three parameters with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + val map: MutableMap = mutableMapOf() + restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC, map) + } + + @Test(expected = UnsupportedOperationException::class, timeout = 300_000) + fun `setProperty with target platform version of 7 throws unsupported exception`() { + whenever(cordapp.targetPlatformVersion).thenReturn(7) + restrictedEntityManager.setProperty("number", 12) + } + + @Test(timeout = 300_000) + fun `close with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedEntityManager.close() + } + + @Test(timeout = 300_000) + fun `clear with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedEntityManager.clear() + } + + @Test(timeout = 300_000) + fun `getMetaModel with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedEntityManager.metamodel + } + + @Test(timeout = 300_000) + fun `getTransaction with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + whenever(entitymanager.transaction).doReturn(transaction) + assertTrue(restrictedEntityManager.transaction is RestrictedEntityTransaction) + } + + @Test(timeout = 300_000) + fun `joinTransaction with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedEntityManager.joinTransaction() + } + + @Test(timeout = 300_000) + fun `lock with two parameters with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC) + } + + @Test(timeout = 300_000) + fun `lock with three parameters with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) + val map: MutableMap = mutableMapOf() + restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC, map) + } + + @Test(timeout = 300_000) + fun `setProperty with target platform version of 6 executes successfully`() { + whenever(cordapp.targetPlatformVersion).thenReturn(6) restrictedEntityManager.setProperty("number", 12) } } \ No newline at end of file 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 589709abd1..ef8fd825a6 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -1144,7 +1144,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, /** * Exposes the database connection as a [RestrictedConnection] to the users. */ - override fun jdbcSession(): Connection = RestrictedConnection(database.createSession()) + override fun jdbcSession(): Connection = RestrictedConnection(database.createSession(), services) @Suppress("TooGenericExceptionCaught") override fun withEntityManager(block: EntityManager.() -> T): T { @@ -1154,7 +1154,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, withSavePoint { savepoint -> // Restrict what entity manager they can use inside the block try { - block(RestrictedEntityManager(manager)).also { + block(RestrictedEntityManager(manager, services)).also { if (!manager.transaction.rollbackOnly) { manager.flush() } else { From e00bd93478f0d5dbb5006bdb1b60194777cb4005 Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Tue, 22 Feb 2022 08:35:17 +0000 Subject: [PATCH 07/28] INFRA-1386 - remove nightly publish to dockerhub (#6908) (#7078) * INFRA-1386 - remove nightly publish to dockerhub. * Remove entirely. Co-authored-by: Dries Samyn --- .ci/dev/publish-branch/Jenkinsfile.nightly | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.ci/dev/publish-branch/Jenkinsfile.nightly b/.ci/dev/publish-branch/Jenkinsfile.nightly index f0cff55966..b7b36f7eb8 100644 --- a/.ci/dev/publish-branch/Jenkinsfile.nightly +++ b/.ci/dev/publish-branch/Jenkinsfile.nightly @@ -112,22 +112,6 @@ pipeline { ) } } - - stage('Publish Nightly to Docker Hub') { - steps { - withCredentials([ - usernamePassword(credentialsId: 'corda-publisher-docker-hub-credentials', - usernameVariable: 'DOCKER_USERNAME', - passwordVariable: 'DOCKER_PASSWORD')]) { - sh script: [ - './gradlew', - 'docker:pushDockerImage', - '-Pdocker.image.repository=corda/corda', - '--image OFFICIAL' - ].join(' ') - } - } - } } From 9dfdd71c223ed6dc3d2d9fabfb3c9a7c44ecae33 Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Thu, 24 Feb 2022 13:26:37 +0000 Subject: [PATCH 08/28] ENT-6631 - upgrade jackson version to get rid of databind vulnerability, keeping jackson-module-kotlin the same --- build.gradle | 3 ++- client/jackson/build.gradle | 4 +++- samples/irs-demo/cordapp/workflows-irs/build.gradle | 2 +- samples/irs-demo/web/build.gradle | 2 +- testing/test-cli/build.gradle | 2 +- tools/network-builder/build.gradle | 2 +- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 9b5f73b2d0..a70e192e53 100644 --- a/build.gradle +++ b/build.gradle @@ -63,7 +63,8 @@ buildscript { ext.asm_version = '7.1' ext.artemis_version = '2.19.1' // TODO Upgrade Jackson only when corda is using kotlin 1.3.10 - ext.jackson_version = '2.9.7' + ext.jackson_version = '2.11.1' + ext.jackson_kotlin_version = '2.9.7' ext.jetty_version = '9.4.19.v20190610' ext.jersey_version = '2.25' ext.servlet_version = '4.0.1' diff --git a/client/jackson/build.gradle b/client/jackson/build.gradle index e586479b80..b86798a8b3 100644 --- a/client/jackson/build.gradle +++ b/client/jackson/build.gradle @@ -9,7 +9,9 @@ dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // Jackson and its plugins: parsing to/from JSON and other textual formats. - compile "com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_version" + compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_kotlin_version") { + exclude module: "jackson-databind" + } // Yaml is useful for parsing strings to method calls. compile "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jackson_version" // This adds support for java.time types. diff --git a/samples/irs-demo/cordapp/workflows-irs/build.gradle b/samples/irs-demo/cordapp/workflows-irs/build.gradle index ce09b2a803..ff88428b24 100644 --- a/samples/irs-demo/cordapp/workflows-irs/build.gradle +++ b/samples/irs-demo/cordapp/workflows-irs/build.gradle @@ -16,7 +16,7 @@ dependencies { cordaCompile project(':core') - compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_version") + compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_kotlin_version") // only included to control the `DemoClock` as part of the demo application // normally `:node` should not be depended on in any CorDapps diff --git a/samples/irs-demo/web/build.gradle b/samples/irs-demo/web/build.gradle index 8064af4347..b887d036cb 100644 --- a/samples/irs-demo/web/build.gradle +++ b/samples/irs-demo/web/build.gradle @@ -70,7 +70,7 @@ dependencies { } compile('org.springframework.boot:spring-boot-starter-log4j2') runtimeOnly("org.apache.logging.log4j:log4j-web:$log4j_version") - compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_version") + compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_kotlin_version") compile project(":client:rpc") compile project(":client:jackson") compile project(":finance:workflows") diff --git a/testing/test-cli/build.gradle b/testing/test-cli/build.gradle index a668c605f4..d4de7deba0 100644 --- a/testing/test-cli/build.gradle +++ b/testing/test-cli/build.gradle @@ -6,7 +6,7 @@ dependencies { compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jackson_version" compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" - compile "com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_version" + compile "com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_kotlin_version" compile "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}" compile "junit:junit:${junit_version}" diff --git a/tools/network-builder/build.gradle b/tools/network-builder/build.gradle index 1790147579..51ec4d6339 100644 --- a/tools/network-builder/build.gradle +++ b/tools/network-builder/build.gradle @@ -52,7 +52,7 @@ dependencies { compile "com.typesafe:config:$typesafe_config_version" compile "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jackson_version" compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" - compile "com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_version" + compile "com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_kotlin_version" compile "info.picocli:picocli:$picocli_version" // TornadoFX: A lightweight Kotlin framework for working with JavaFX UI's. From 4b29ad337bb15f75dc984fb7f97f0e87057df6f3 Mon Sep 17 00:00:00 2001 From: Dan Newton Date: Fri, 25 Feb 2022 15:47:31 +0000 Subject: [PATCH 09/28] ENT-6710 Corda shell ssh logging again (#7093) Correct SSH logging again, by pulling the logging of SSH ports to a singular location. --- .../kotlin/net/corda/node/internal/AbstractNode.kt | 8 ++++++-- .../kotlin/net/corda/node/internal/NodeStartup.kt | 14 +------------- 2 files changed, 7 insertions(+), 15 deletions(-) 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 82eacfcbf4..2f2479c139 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -690,9 +690,13 @@ abstract class AbstractNode(val configuration: NodeConfiguration, val isShellStarted = InteractiveShell.startShellIfInstalled(configuration, cordappLoader) configuration.sshd?.port?.let { if (isShellStarted) { - log.info("Binding Shell SSHD server on port $it.") + Node.printBasicNodeInfo("SSH server listening on port", configuration.sshd!!.port.toString()) + log.info("SSH server listening on port: $it.") } else { - log.info("SSH port defined but corda-shell is not installed in node's drivers directory") + Node.printBasicNodeInfo( + "SSH server not started. SSH port is defined but the corda-shell is not installed in node's drivers directory" + ) + log.info("SSH server not started. SSH port is defined but the corda-shell is not installed in node's drivers directory") } } } diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt index 0e90920616..1772210e56 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -48,7 +48,6 @@ import net.corda.node.internal.subcommands.ValidateConfigurationCli.Companion.lo import net.corda.node.internal.subcommands.ValidateConfigurationCli.Companion.logRawConfig import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.shouldStartLocalShell -import net.corda.node.services.config.shouldStartSSHDaemon import net.corda.node.utilities.registration.NodeRegistrationException import net.corda.nodeapi.internal.JVMAgentUtilities import net.corda.nodeapi.internal.addShutdownHook @@ -263,19 +262,8 @@ open class NodeStartup : NodeStartupLogging { Node.printBasicNodeInfo("Node for \"$name\" started up and registered in $elapsed sec") // Don't start the shell if there's no console attached. - val isShellStarted = if (node.configuration.shouldStartLocalShell()) { + if (node.configuration.shouldStartLocalShell()) { InteractiveShell.runLocalShellIfInstalled(node::stop) - } else { - false - } - if (node.configuration.shouldStartSSHDaemon()) { - if (isShellStarted) { - Node.printBasicNodeInfo("SSH server listening on port", node.configuration.sshd!!.port.toString()) - } else { - Node.printBasicNodeInfo( - "SSH server not started. SSH port is defined but the corda-shell is not installed in node's drivers directory" - ) - } } }, { th -> From 5f1e86c17c98ca6c4c9b0e0cb7fe3cb8db7ff919 Mon Sep 17 00:00:00 2001 From: Conal Smith <68279385+conalsmith-r3@users.noreply.github.com> Date: Fri, 25 Feb 2022 15:51:49 +0000 Subject: [PATCH 10/28] ENT-6508 - Prevent directory traversal from zip file names (#7085) --- .../persistence/NodeAttachmentService.kt | 3 ++ .../persistence/NodeAttachmentServiceTest.kt | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt b/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt index e6aee94e7f..6ea173ef4d 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt @@ -88,6 +88,9 @@ class NodeAttachmentService @JvmOverloads constructor( while (true) { val cursor = jar.nextJarEntry ?: break + // Security check to stop directory traversal from filename entry + require(!(cursor.name.contains("../"))) { "Bad character in ${cursor.name}" } + require(!(cursor.name.contains("..\\"))) { "Bad character in ${cursor.name}" } if (manifestHasEntries && !allManifestEntries!!.remove(cursor.name)) extraFilesNotFoundInEntries.add(cursor) val entryPath = Paths.get(cursor.name) // Security check to stop zips trying to escape their rightful place. diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentServiceTest.kt index e419df5d01..7c52587a3f 100644 --- a/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentServiceTest.kt @@ -46,14 +46,19 @@ import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Ignore import org.junit.Test +import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream +import java.io.InputStream import java.net.URL import java.nio.charset.StandardCharsets import java.nio.file.FileAlreadyExistsException import java.nio.file.FileSystem import java.nio.file.Path import java.util.* +import java.util.jar.JarEntry import java.util.jar.JarInputStream +import java.util.jar.JarOutputStream +import java.util.jar.Manifest import kotlin.streams.toList import kotlin.test.* @@ -788,6 +793,32 @@ class NodeAttachmentServiceTest { } } + @Test(timeout=300_000) + fun `attachments containing jar entries whose names expose malicious directory traversal are prevented`() { + + fun createJarWithJarEntryTraversalAttack(jarEntryName: String): InputStream { + val byteArrayOutputStream = ByteArrayOutputStream() + JarOutputStream(byteArrayOutputStream, Manifest()).apply { + putNextEntry(JarEntry(jarEntryName)) + write("some-text".toByteArray()) + closeEntry() + close() + } + return ByteArrayInputStream(byteArrayOutputStream.toByteArray()) + } + + val traversalAttackJarWin = createJarWithJarEntryTraversalAttack("..\\attack") + val traversalAttackJarUnix = createJarWithJarEntryTraversalAttack("../attack") + + assertFailsWith(IllegalArgumentException::class) { + NodeAttachmentService.checkIsAValidJAR(traversalAttackJarWin) + } + + assertFailsWith(IllegalArgumentException::class) { + NodeAttachmentService.checkIsAValidJAR(traversalAttackJarUnix) + } + } + @Test(timeout=300_000) fun `attachments can be queried by providing a intersection of signers using an EQUAL statement - EQUAL containing a single public key`() { SelfCleaningDir().use { file -> From 96576a7278291f14281a4e82f4a1c19a2878b186 Mon Sep 17 00:00:00 2001 From: Adel El-Beik Date: Tue, 1 Mar 2022 12:35:46 +0000 Subject: [PATCH 11/28] ENT-6687: Updated build.gradle so corda-shell is copied into drivers directory. --- samples/attachment-demo/build.gradle | 1 + samples/bank-of-corda-demo/build.gradle | 1 + samples/cordapp-configuration/build.gradle | 1 + samples/irs-demo/cordapp/build.gradle | 1 + samples/network-verifier/build.gradle | 1 + samples/notary-demo/build.gradle | 1 + samples/simm-valuation-demo/build.gradle | 1 + samples/trader-demo/build.gradle | 1 + 8 files changed, 8 insertions(+) diff --git a/samples/attachment-demo/build.gradle b/samples/attachment-demo/build.gradle index 0e6000cbe2..7d4f973a63 100644 --- a/samples/attachment-demo/build.gradle +++ b/samples/attachment-demo/build.gradle @@ -31,6 +31,7 @@ configurations { } dependencies { + cordaDriver "net.corda:corda-shell:$corda_release_version" compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" compile "net.sf.jopt-simple:jopt-simple:$jopt_simple_version" compile "javax.servlet:javax.servlet-api:${servlet_version}" diff --git a/samples/bank-of-corda-demo/build.gradle b/samples/bank-of-corda-demo/build.gradle index aa377a6cee..0b12928f0b 100644 --- a/samples/bank-of-corda-demo/build.gradle +++ b/samples/bank-of-corda-demo/build.gradle @@ -6,6 +6,7 @@ apply plugin: 'net.corda.plugins.cordapp' apply plugin: 'net.corda.plugins.cordformation' dependencies { + cordaDriver "net.corda:corda-shell:$corda_release_version" compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // The bank of corda CorDapp depends upon Cash CorDapp features diff --git a/samples/cordapp-configuration/build.gradle b/samples/cordapp-configuration/build.gradle index 4c57c1b941..efa92053c5 100644 --- a/samples/cordapp-configuration/build.gradle +++ b/samples/cordapp-configuration/build.gradle @@ -3,6 +3,7 @@ apply plugin: 'idea' apply plugin: 'net.corda.plugins.cordformation' dependencies { + cordaDriver "net.corda:corda-shell:$corda_release_version" runtimeOnly project(':node-api') // Cordformation needs a SLF4J implementation when executing the Network // Bootstrapper, but Log4J doesn't shutdown completely from within Gradle. diff --git a/samples/irs-demo/cordapp/build.gradle b/samples/irs-demo/cordapp/build.gradle index e46aea2330..625a9e20e6 100644 --- a/samples/irs-demo/cordapp/build.gradle +++ b/samples/irs-demo/cordapp/build.gradle @@ -27,6 +27,7 @@ cordapp { } dependencies { + cordaDriver "net.corda:corda-shell:$corda_release_version" cordapp project(':finance:contracts') cordapp project(':finance:workflows') diff --git a/samples/network-verifier/build.gradle b/samples/network-verifier/build.gradle index ab6d4d37a5..9aaef448ed 100644 --- a/samples/network-verifier/build.gradle +++ b/samples/network-verifier/build.gradle @@ -12,6 +12,7 @@ cordapp { } dependencies { + cordaDriver "net.corda:corda-shell:$corda_release_version" // Cordformation needs this for the Network Bootstrapper. runtimeOnly project(':node-api') diff --git a/samples/notary-demo/build.gradle b/samples/notary-demo/build.gradle index 1cd9710a65..bcaeac96af 100644 --- a/samples/notary-demo/build.gradle +++ b/samples/notary-demo/build.gradle @@ -15,6 +15,7 @@ cordapp { } dependencies { + cordaDriver "net.corda:corda-shell:$corda_release_version" compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" cordaCompile project(':client:rpc') // Corda integration dependencies diff --git a/samples/simm-valuation-demo/build.gradle b/samples/simm-valuation-demo/build.gradle index 7f2f3e17bc..ef95f82e5c 100644 --- a/samples/simm-valuation-demo/build.gradle +++ b/samples/simm-valuation-demo/build.gradle @@ -26,6 +26,7 @@ configurations { } dependencies { + cordaDriver "net.corda:corda-shell:$corda_release_version" cordaCompile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // The SIMM demo CorDapp depends upon Cash CorDapp features diff --git a/samples/trader-demo/build.gradle b/samples/trader-demo/build.gradle index 68cffdff69..8b38fdc80d 100644 --- a/samples/trader-demo/build.gradle +++ b/samples/trader-demo/build.gradle @@ -32,6 +32,7 @@ configurations { } dependencies { + cordaDriver "net.corda:corda-shell:$corda_release_version" compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" compile "net.sf.jopt-simple:jopt-simple:$jopt_simple_version" cordaCompile project(':client:rpc') From 4203a56c3a521adf97edee7ec8c4a421a0e4bda0 Mon Sep 17 00:00:00 2001 From: Adel El-Beik Date: Thu, 3 Mar 2022 16:40:18 +0000 Subject: [PATCH 12/28] ENT-6637 & ENT-6618: Removed jgroups and dbcp from artemis dependencies. --- build.gradle | 2 ++ node/build.gradle | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a70e192e53..464ba6903a 100644 --- a/build.gradle +++ b/build.gradle @@ -460,6 +460,8 @@ allprojects { // Netty-All is an uber-jar which contains every Netty module. // Exclude it to force us to use the individual Netty modules instead. exclude group: 'io.netty', module: 'netty-all' + + exclude group: 'org.jgroups', module: 'jgroups' } runtime { // We never want isolated.jar on classPath, since we want to test jar being dynamically loaded as an attachment diff --git a/node/build.gradle b/node/build.gradle index 9b82652aeb..bbf541f824 100644 --- a/node/build.gradle +++ b/node/build.gradle @@ -127,7 +127,9 @@ dependencies { // TODO: remove the forced update of commons-collections and beanutils when artemis updates them compile "org.apache.commons:commons-collections4:${commons_collections_version}" compile "commons-beanutils:commons-beanutils:${beanutils_version}" - compile "org.apache.activemq:artemis-server:${artemis_version}" + compile("org.apache.activemq:artemis-server:${artemis_version}") { + exclude group: 'org.apache.commons', module: 'commons-dbcp2' + } compile "org.apache.activemq:artemis-core-client:${artemis_version}" runtime("org.apache.activemq:artemis-amqp-protocol:${artemis_version}") { // Gains our proton-j version from core module. From 4594c76259cec500b331eaac4c2acd0071ce56bf Mon Sep 17 00:00:00 2001 From: Adel El-Beik Date: Fri, 4 Mar 2022 11:52:14 +0000 Subject: [PATCH 13/28] ENT-6637: Targeted exclude of the jgroups dependency. --- build.gradle | 2 -- client/jfx/build.gradle | 4 +++- node-api/build.gradle | 5 ++++- node/build.gradle | 6 +++++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 464ba6903a..a70e192e53 100644 --- a/build.gradle +++ b/build.gradle @@ -460,8 +460,6 @@ allprojects { // Netty-All is an uber-jar which contains every Netty module. // Exclude it to force us to use the individual Netty modules instead. exclude group: 'io.netty', module: 'netty-all' - - exclude group: 'org.jgroups', module: 'jgroups' } runtime { // We never want isolated.jar on classPath, since we want to test jar being dynamically loaded as an attachment diff --git a/client/jfx/build.gradle b/client/jfx/build.gradle index d8a1b514ec..06c1bbbd93 100644 --- a/client/jfx/build.gradle +++ b/client/jfx/build.gradle @@ -55,7 +55,9 @@ dependencies { // TODO: remove the forced update of commons-collections and beanutils when artemis updates them compile "org.apache.commons:commons-collections4:${commons_collections_version}" compile "commons-beanutils:commons-beanutils:${beanutils_version}" - compile "org.apache.activemq:artemis-core-client:${artemis_version}" + compile("org.apache.activemq:artemis-core-client:${artemis_version}") { + exclude group: 'org.jgroups', module: 'jgroups' + } // Unit testing helpers. testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}" diff --git a/node-api/build.gradle b/node-api/build.gradle index b47bc040be..7299cfa23e 100644 --- a/node-api/build.gradle +++ b/node-api/build.gradle @@ -17,7 +17,9 @@ dependencies { // TODO: remove the forced update of commons-collections and beanutils when artemis updates them compile "org.apache.commons:commons-collections4:${commons_collections_version}" compile "commons-beanutils:commons-beanutils:${beanutils_version}" - compile "org.apache.activemq:artemis-core-client:${artemis_version}" + compile("org.apache.activemq:artemis-core-client:${artemis_version}") { + exclude group: 'org.jgroups', module: 'jgroups' + } compile "org.apache.activemq:artemis-commons:${artemis_version}" compile "io.netty:netty-handler-proxy:$netty_version" @@ -62,6 +64,7 @@ dependencies { compile ("org.apache.activemq:artemis-amqp-protocol:${artemis_version}") { // Gains our proton-j version from core module. exclude group: 'org.apache.qpid', module: 'proton-j' + exclude group: 'org.jgroups', module: 'jgroups' } } diff --git a/node/build.gradle b/node/build.gradle index bbf541f824..0b4a47213d 100644 --- a/node/build.gradle +++ b/node/build.gradle @@ -129,11 +129,15 @@ dependencies { compile "commons-beanutils:commons-beanutils:${beanutils_version}" compile("org.apache.activemq:artemis-server:${artemis_version}") { exclude group: 'org.apache.commons', module: 'commons-dbcp2' + exclude group: 'org.jgroups', module: 'jgroups' + } + compile("org.apache.activemq:artemis-core-client:${artemis_version}") { + exclude group: 'org.jgroups', module: 'jgroups' } - compile "org.apache.activemq:artemis-core-client:${artemis_version}" runtime("org.apache.activemq:artemis-amqp-protocol:${artemis_version}") { // Gains our proton-j version from core module. exclude group: 'org.apache.qpid', module: 'proton-j' + exclude group: 'org.jgroups', module: 'jgroups' } // Manifests: for reading stuff from the manifest file From 1e227fdfc458540672993130625cb51ec1f95e70 Mon Sep 17 00:00:00 2001 From: Rick Parker Date: Mon, 7 Mar 2022 11:08:06 +0000 Subject: [PATCH 14/28] ENT-6711 - Fix for upgrade to Jackson 2.12 and beyond (actual upgrade to 2.13.1) (#7096) * NOTICK - Don't know what the JIRA is but wanted to share. * Updates to resolve bukld issues * NOTICK: Fixed JDK11 version to prevent capsule version error * ENT-6711: Added comment for use of jackson_kotlin_version. * ENT-6711: Avoid deprecation warning, switched to the default method. Co-authored-by: Chris Cochrane Co-authored-by: Adel El-Beik --- .ci/dev/compatibility/DockerfileJDK11 | 2 +- build.gradle | 2 +- .../corda/client/jackson/JacksonSupport.kt | 38 ++++++++++-- .../client/jackson/internal/CordaModule.kt | 58 +++++++++++++++++-- .../node/services/rpc/CheckpointDumperImpl.kt | 2 +- samples/irs-demo/build.gradle | 3 +- 6 files changed, 90 insertions(+), 15 deletions(-) diff --git a/.ci/dev/compatibility/DockerfileJDK11 b/.ci/dev/compatibility/DockerfileJDK11 index 263c42a391..ff6eeaac95 100644 --- a/.ci/dev/compatibility/DockerfileJDK11 +++ b/.ci/dev/compatibility/DockerfileJDK11 @@ -1,4 +1,4 @@ -FROM azul/zulu-openjdk:11 +FROM azul/zulu-openjdk:11.0.14 RUN apt-get update && apt-get install -y curl apt-transport-https \ ca-certificates \ curl \ diff --git a/build.gradle b/build.gradle index a70e192e53..0407a5c69b 100644 --- a/build.gradle +++ b/build.gradle @@ -63,7 +63,7 @@ buildscript { ext.asm_version = '7.1' ext.artemis_version = '2.19.1' // TODO Upgrade Jackson only when corda is using kotlin 1.3.10 - ext.jackson_version = '2.11.1' + ext.jackson_version = '2.13.1' ext.jackson_kotlin_version = '2.9.7' ext.jetty_version = '9.4.19.v20190610' ext.jersey_version = '2.25' diff --git a/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt b/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt index 95f6f3e03c..46d7c105f3 100644 --- a/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt +++ b/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt @@ -2,10 +2,24 @@ package net.corda.client.jackson import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.core.* -import com.fasterxml.jackson.databind.* +import com.fasterxml.jackson.core.JsonFactory +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.JsonParseException +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.core.JsonToken +import com.fasterxml.jackson.databind.BeanDescription +import com.fasterxml.jackson.databind.DeserializationConfig +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.JsonDeserializer +import com.fasterxml.jackson.databind.JsonSerializer +import com.fasterxml.jackson.databind.Module +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.SerializationFeature +import com.fasterxml.jackson.databind.SerializerProvider import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.databind.cfg.ConstructorDetector import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier import com.fasterxml.jackson.databind.deser.std.NumberDeserializers import com.fasterxml.jackson.databind.node.ObjectNode @@ -21,9 +35,21 @@ import net.corda.core.DoNotImplement import net.corda.core.contracts.Amount import net.corda.core.contracts.ContractState import net.corda.core.contracts.StateRef -import net.corda.core.crypto.* -import net.corda.core.identity.* -import net.corda.core.internal.* +import net.corda.core.crypto.Base58 +import net.corda.core.crypto.MerkleTree +import net.corda.core.crypto.SecureHash +import net.corda.core.crypto.TransactionSignature +import net.corda.core.crypto.toStringShort +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.identity.PartyAndCertificate +import net.corda.core.internal.CertRole +import net.corda.core.internal.VisibleForTesting +import net.corda.core.internal.isStatic +import net.corda.core.internal.kotlinObjectInstance +import net.corda.core.internal.uncheckedCast import net.corda.core.messaging.CordaRPCOps import net.corda.core.node.NodeInfo import net.corda.core.node.services.IdentityService @@ -179,6 +205,8 @@ object JacksonSupport { addMixIn(X500Principal::class.java, X500PrincipalMixin::class.java) addMixIn(X509Certificate::class.java, X509CertificateMixin::class.java) addMixIn(CertPath::class.java, CertPathMixin::class.java) + + setConstructorDetector(ConstructorDetector.DEFAULT.withAllowJDKTypeConstructors(true)) } } diff --git a/client/jackson/src/main/kotlin/net/corda/client/jackson/internal/CordaModule.kt b/client/jackson/src/main/kotlin/net/corda/client/jackson/internal/CordaModule.kt index 17e98ffd22..24e3efd707 100644 --- a/client/jackson/src/main/kotlin/net/corda/client/jackson/internal/CordaModule.kt +++ b/client/jackson/src/main/kotlin/net/corda/client/jackson/internal/CordaModule.kt @@ -2,16 +2,30 @@ package net.corda.client.jackson.internal -import com.fasterxml.jackson.annotation.* import com.fasterxml.jackson.annotation.JsonAutoDetect.Value import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility +import com.fasterxml.jackson.annotation.JsonCreator import com.fasterxml.jackson.annotation.JsonCreator.Mode.DISABLED +import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonInclude.Include +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonTypeInfo +import com.fasterxml.jackson.annotation.JsonValue import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParseException import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.core.JsonToken -import com.fasterxml.jackson.databind.* +import com.fasterxml.jackson.databind.BeanDescription +import com.fasterxml.jackson.databind.BeanProperty +import com.fasterxml.jackson.databind.DeserializationConfig +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JavaType +import com.fasterxml.jackson.databind.JsonDeserializer +import com.fasterxml.jackson.databind.JsonSerializer +import com.fasterxml.jackson.databind.Module +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.SerializationConfig +import com.fasterxml.jackson.databind.SerializerProvider import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.databind.cfg.MapperConfig @@ -19,6 +33,7 @@ import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier import com.fasterxml.jackson.databind.deser.ContextualDeserializer import com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer import com.fasterxml.jackson.databind.deser.std.FromStringDeserializer +import com.fasterxml.jackson.databind.introspect.AccessorNamingStrategy import com.fasterxml.jackson.databind.introspect.AnnotatedClass import com.fasterxml.jackson.databind.introspect.BasicClassIntrospector import com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector @@ -31,12 +46,30 @@ import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer import com.fasterxml.jackson.databind.ser.std.UUIDSerializer import com.google.common.primitives.Booleans import net.corda.client.jackson.JacksonSupport -import net.corda.core.contracts.* -import net.corda.core.crypto.* +import net.corda.core.contracts.Amount +import net.corda.core.contracts.AttachmentConstraint +import net.corda.core.contracts.Command +import net.corda.core.contracts.CommandData +import net.corda.core.contracts.ContractState +import net.corda.core.contracts.PrivacySalt +import net.corda.core.contracts.StateRef +import net.corda.core.contracts.TimeWindow +import net.corda.core.contracts.TransactionState +import net.corda.core.crypto.Crypto +import net.corda.core.crypto.DigestService +import net.corda.core.crypto.DigitalSignature import net.corda.core.crypto.PartialMerkleTree.PartialTree +import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash.Companion.SHA2_256 +import net.corda.core.crypto.SignatureMetadata +import net.corda.core.crypto.SignatureScheme +import net.corda.core.crypto.TransactionSignature import net.corda.core.flows.StateMachineRunId -import net.corda.core.identity.* +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.identity.PartyAndCertificate import net.corda.core.internal.DigitalSignatureWithCert import net.corda.core.internal.createComponentGroups import net.corda.core.node.NodeInfo @@ -44,7 +77,12 @@ import net.corda.core.serialization.SerializeAsToken import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize -import net.corda.core.transactions.* +import net.corda.core.transactions.ContractUpgradeFilteredTransaction +import net.corda.core.transactions.ContractUpgradeWireTransaction +import net.corda.core.transactions.FilteredTransaction +import net.corda.core.transactions.NotaryChangeWireTransaction +import net.corda.core.transactions.SignedTransaction +import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.ByteSequence import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.parseAsHex @@ -117,6 +155,14 @@ private class CordaSerializableClassIntrospector(private val context: Module.Set } return super.constructPropertyCollector(config, ac, type, forSerialization, mutatorPrefix) } + + override fun constructPropertyCollector(config: MapperConfig<*>?, classDef: AnnotatedClass?, type: JavaType, forSerialization: Boolean, accNaming: AccessorNamingStrategy?): POJOPropertiesCollector { + if (hasCordaSerializable(type.rawClass)) { + // Adjust the field visibility of CordaSerializable classes on the fly as they are encountered. + context.configOverride(type.rawClass).visibility = Value.defaultVisibility().withFieldVisibility(Visibility.ANY) + } + return super.constructPropertyCollector(config, classDef, type, forSerialization, accNaming) + } } private class CordaSerializableBeanSerializerModifier : BeanSerializerModifier() { diff --git a/node/src/main/kotlin/net/corda/node/services/rpc/CheckpointDumperImpl.kt b/node/src/main/kotlin/net/corda/node/services/rpc/CheckpointDumperImpl.kt index 4e2e2a3153..a9aceab60b 100644 --- a/node/src/main/kotlin/net/corda/node/services/rpc/CheckpointDumperImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/rpc/CheckpointDumperImpl.kt @@ -584,7 +584,7 @@ class CheckpointDumperImpl(private val checkpointStorage: CheckpointStorage, pri private object MapSerializer : JsonSerializer>() { override fun serialize(map: Map, gen: JsonGenerator, serializers: SerializerProvider) { - gen.writeStartArray(map.size) + gen.writeStartArray() map.forEach { (key, value) -> gen.jsonObject { writeObjectField("key", key) diff --git a/samples/irs-demo/build.gradle b/samples/irs-demo/build.gradle index 700dd73dc4..0cf5896f9a 100644 --- a/samples/irs-demo/build.gradle +++ b/samples/irs-demo/build.gradle @@ -9,7 +9,8 @@ plugins { ext['artemis.version'] = "$artemis_version" ext['hibernate.version'] = "$hibernate_version" ext['selenium.version'] = "$selenium_version" -ext['jackson.version'] = "$jackson_version" +// Using jackson_kotlin_version here for JDK11 compatibility with kotlin 1.2.71 +ext['jackson.version'] = "$jackson_kotlin_version" ext['dropwizard-metrics.version'] = "$metrics_version" ext['mockito.version'] = "$mockito_version" From e1746e068cb4b5970f3c4250e0a1fd273afaaea5 Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Mon, 7 Mar 2022 17:00:10 +0000 Subject: [PATCH 15/28] NOTICK: add flag to ensure API docs are published as part of release process (#7103) --- .ci/dev/regression/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 82d0f66399..5a4137af2a 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -271,7 +271,7 @@ pipeline { rtGradleRun( usesPlugin: true, useWrapper: true, - switches: '-s --info', + switches: '-s --info -DpublishApiDocs', tasks: 'artifactoryPublish', deployerId: 'deployer', buildName: env.ARTIFACTORY_BUILD_NAME From ee8eac4516301043414a77d0bc9f0e29ab309f7a Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Tue, 8 Mar 2022 10:50:59 +0000 Subject: [PATCH 16/28] NOTICK: release support optionally exclude shell dependency --- .ci/dev/regression/Jenkinsfile | 1 + samples/attachment-demo/build.gradle | 4 +++- samples/bank-of-corda-demo/build.gradle | 4 +++- samples/cordapp-configuration/build.gradle | 4 +++- samples/irs-demo/cordapp/build.gradle | 4 +++- samples/network-verifier/build.gradle | 4 +++- samples/notary-demo/build.gradle | 4 +++- samples/simm-valuation-demo/build.gradle | 5 +++-- samples/trader-demo/build.gradle | 4 +++- 9 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 5a4137af2a..980d7a4593 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -49,6 +49,7 @@ String COMMON_GRADLE_PARAMS = [ '--info', '-Pcompilation.warningsAsErrors=false', '-Ptests.failFast=true', + '-DexcludeShell', ].join(' ') pipeline { diff --git a/samples/attachment-demo/build.gradle b/samples/attachment-demo/build.gradle index 7d4f973a63..02fa732184 100644 --- a/samples/attachment-demo/build.gradle +++ b/samples/attachment-demo/build.gradle @@ -31,7 +31,9 @@ configurations { } dependencies { - cordaDriver "net.corda:corda-shell:$corda_release_version" + if (System.getProperty('excludeShell') == null) { + cordaDriver "net.corda:corda-shell:$corda_release_version" + } compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" compile "net.sf.jopt-simple:jopt-simple:$jopt_simple_version" compile "javax.servlet:javax.servlet-api:${servlet_version}" diff --git a/samples/bank-of-corda-demo/build.gradle b/samples/bank-of-corda-demo/build.gradle index 0b12928f0b..11d398ce8b 100644 --- a/samples/bank-of-corda-demo/build.gradle +++ b/samples/bank-of-corda-demo/build.gradle @@ -6,7 +6,9 @@ apply plugin: 'net.corda.plugins.cordapp' apply plugin: 'net.corda.plugins.cordformation' dependencies { - cordaDriver "net.corda:corda-shell:$corda_release_version" + if (System.getProperty('excludeShell') == null) { + cordaDriver "net.corda:corda-shell:$corda_release_version" + } compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // The bank of corda CorDapp depends upon Cash CorDapp features diff --git a/samples/cordapp-configuration/build.gradle b/samples/cordapp-configuration/build.gradle index efa92053c5..5f1155c184 100644 --- a/samples/cordapp-configuration/build.gradle +++ b/samples/cordapp-configuration/build.gradle @@ -3,7 +3,9 @@ apply plugin: 'idea' apply plugin: 'net.corda.plugins.cordformation' dependencies { - cordaDriver "net.corda:corda-shell:$corda_release_version" + if (System.getProperty('excludeShell') == null) { + cordaDriver "net.corda:corda-shell:$corda_release_version" + } runtimeOnly project(':node-api') // Cordformation needs a SLF4J implementation when executing the Network // Bootstrapper, but Log4J doesn't shutdown completely from within Gradle. diff --git a/samples/irs-demo/cordapp/build.gradle b/samples/irs-demo/cordapp/build.gradle index 625a9e20e6..71d0428949 100644 --- a/samples/irs-demo/cordapp/build.gradle +++ b/samples/irs-demo/cordapp/build.gradle @@ -27,7 +27,9 @@ cordapp { } dependencies { - cordaDriver "net.corda:corda-shell:$corda_release_version" + if (System.getProperty('excludeShell') == null) { + cordaDriver "net.corda:corda-shell:$corda_release_version" + } cordapp project(':finance:contracts') cordapp project(':finance:workflows') diff --git a/samples/network-verifier/build.gradle b/samples/network-verifier/build.gradle index 9aaef448ed..1cd1c9f4b8 100644 --- a/samples/network-verifier/build.gradle +++ b/samples/network-verifier/build.gradle @@ -12,7 +12,9 @@ cordapp { } dependencies { - cordaDriver "net.corda:corda-shell:$corda_release_version" + if (System.getProperty('excludeShell') == null) { + cordaDriver "net.corda:corda-shell:$corda_release_version" + } // Cordformation needs this for the Network Bootstrapper. runtimeOnly project(':node-api') diff --git a/samples/notary-demo/build.gradle b/samples/notary-demo/build.gradle index bcaeac96af..6f87b55b35 100644 --- a/samples/notary-demo/build.gradle +++ b/samples/notary-demo/build.gradle @@ -15,7 +15,9 @@ cordapp { } dependencies { - cordaDriver "net.corda:corda-shell:$corda_release_version" + if (System.getProperty('excludeShell') == null) { + cordaDriver "net.corda:corda-shell:$corda_release_version" + } compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" cordaCompile project(':client:rpc') // Corda integration dependencies diff --git a/samples/simm-valuation-demo/build.gradle b/samples/simm-valuation-demo/build.gradle index ef95f82e5c..0609747f93 100644 --- a/samples/simm-valuation-demo/build.gradle +++ b/samples/simm-valuation-demo/build.gradle @@ -26,9 +26,10 @@ configurations { } dependencies { - cordaDriver "net.corda:corda-shell:$corda_release_version" + if (System.getProperty('excludeShell') == null) { + cordaDriver "net.corda:corda-shell:$corda_release_version" + } cordaCompile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - // The SIMM demo CorDapp depends upon Cash CorDapp features cordapp project(':finance:contracts') cordapp project(':finance:workflows') diff --git a/samples/trader-demo/build.gradle b/samples/trader-demo/build.gradle index 8b38fdc80d..0b5272f7a7 100644 --- a/samples/trader-demo/build.gradle +++ b/samples/trader-demo/build.gradle @@ -32,7 +32,9 @@ configurations { } dependencies { - cordaDriver "net.corda:corda-shell:$corda_release_version" + if (System.getProperty('excludeShell') == null) { + cordaDriver "net.corda:corda-shell:$corda_release_version" + } compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" compile "net.sf.jopt-simple:jopt-simple:$jopt_simple_version" cordaCompile project(':client:rpc') From 40a72a483753d0a71b23958a99eb08c015c05141 Mon Sep 17 00:00:00 2001 From: Adel El-Beik <48713346+adelel1@users.noreply.github.com> Date: Thu, 10 Mar 2022 17:56:09 +0000 Subject: [PATCH 17/28] =?UTF-8?q?ENT-6687:=20Added=20the=20corda-releases?= =?UTF-8?q?=20repo,=20so=20that=20deployNodes=20in=20the=20s=E2=80=A6=20(#?= =?UTF-8?q?7113)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ENT-6687: Added the corda-releases repo, so that deployNodes in the samples can find the corda shell. --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 0407a5c69b..359588cb1f 100644 --- a/build.gradle +++ b/build.gradle @@ -422,6 +422,12 @@ allprojects { includeGroup 'com.github.detro' } } + maven { + url "${artifactory_contextUrl}/corda-releases" + content { + includeModule('net.corda', 'corda-shell') + } + } mavenCentral() jcenter() } From f933d23d26404dcacd892806369ae1803ea7355c Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Thu, 10 Mar 2022 17:59:25 +0000 Subject: [PATCH 18/28] INFRA-1728 set correct java version for JDK 11 base image (#7101) Use Specific JDK version not the latest Java 11 base image --- .ci/dev/compatibility/DockerfileJDK11 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/dev/compatibility/DockerfileJDK11 b/.ci/dev/compatibility/DockerfileJDK11 index ff6eeaac95..23aa144955 100644 --- a/.ci/dev/compatibility/DockerfileJDK11 +++ b/.ci/dev/compatibility/DockerfileJDK11 @@ -6,4 +6,4 @@ RUN apt-get update && apt-get install -y curl apt-transport-https \ software-properties-common \ wget ARG USER="stresstester" -RUN useradd -m ${USER} \ No newline at end of file +RUN useradd -m ${USER} From 4844614314dcd184be09fa56b15e84341c929efe Mon Sep 17 00:00:00 2001 From: Connel McGovern <100574906+mcgovc@users.noreply.github.com> Date: Tue, 15 Mar 2022 07:57:41 +0000 Subject: [PATCH 19/28] INFRA-1735 Teams notification's for C4 (#7106) --- .ci/dev/publish-branch/Jenkinsfile.nightly | 24 ++++++++++++++++++++++ .ci/dev/regression/Jenkinsfile | 24 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/.ci/dev/publish-branch/Jenkinsfile.nightly b/.ci/dev/publish-branch/Jenkinsfile.nightly index b7b36f7eb8..0f38bf9cca 100644 --- a/.ci/dev/publish-branch/Jenkinsfile.nightly +++ b/.ci/dev/publish-branch/Jenkinsfile.nightly @@ -33,6 +33,18 @@ def nexusIqStageChoices = [nexusDefaultIqStage].plus( 'operate' ].minus([nexusDefaultIqStage])) +/** + * define an empty teamsWebHookURL and if it is a Release Branch + * then set it for the Corda 4 Jenkins Connector + */ +boolean isReleaseBranch = (env.BRANCH_NAME =~ /^release\/os\/.*/) +def teamsWebHookURL = "" +if (isReleaseBranch){ + withCredentials([string(credentialsId: 'ms-teams-webhook', variable: 'webhook_url')]) { + teamsWebHookURL = "$webhook_url" + } +} + pipeline { agent { label 'standard' } @@ -42,6 +54,18 @@ pipeline { overrideIndexTriggers(false) timeout(time: 3, unit: 'HOURS') buildDiscarder(logRotator(daysToKeepStr: '14', artifactDaysToKeepStr: '14')) + office365ConnectorWebhooks([[ + name : "Corda 4 Jenkins Connector", + notifyBackToNormal : true, + startNotification : false, + notifyFailure : true, + notifySuccess : true, + notifyNotBuilt : false, + notifyAborted : false, + notifyRepeatedFailure: true, + notifyUnstable : true, + url : "${teamsWebHookURL}" + ]]) } parameters { diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 980d7a4593..a603ef13af 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -7,6 +7,7 @@ /** * Sense environment */ +boolean isReleaseBranch = (env.BRANCH_NAME =~ /^release\/os\/.*/) boolean isReleaseTag = (env.TAG_NAME =~ /^release-.*(? Date: Tue, 15 Mar 2022 07:58:36 +0000 Subject: [PATCH 20/28] INFRA-1735 Teams notification's for C4 (#7108) * INFRA-1728 set correct java version for JDK 11 base image --- .ci/dev/compatibility/DockerfileJDK11 | 2 +- .ci/dev/publish-branch/Jenkinsfile.nightly | 24 ++++++++++++++++++++++ .ci/dev/regression/Jenkinsfile | 24 ++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/.ci/dev/compatibility/DockerfileJDK11 b/.ci/dev/compatibility/DockerfileJDK11 index 263c42a391..ff6eeaac95 100644 --- a/.ci/dev/compatibility/DockerfileJDK11 +++ b/.ci/dev/compatibility/DockerfileJDK11 @@ -1,4 +1,4 @@ -FROM azul/zulu-openjdk:11 +FROM azul/zulu-openjdk:11.0.14 RUN apt-get update && apt-get install -y curl apt-transport-https \ ca-certificates \ curl \ diff --git a/.ci/dev/publish-branch/Jenkinsfile.nightly b/.ci/dev/publish-branch/Jenkinsfile.nightly index b7b36f7eb8..0f38bf9cca 100644 --- a/.ci/dev/publish-branch/Jenkinsfile.nightly +++ b/.ci/dev/publish-branch/Jenkinsfile.nightly @@ -33,6 +33,18 @@ def nexusIqStageChoices = [nexusDefaultIqStage].plus( 'operate' ].minus([nexusDefaultIqStage])) +/** + * define an empty teamsWebHookURL and if it is a Release Branch + * then set it for the Corda 4 Jenkins Connector + */ +boolean isReleaseBranch = (env.BRANCH_NAME =~ /^release\/os\/.*/) +def teamsWebHookURL = "" +if (isReleaseBranch){ + withCredentials([string(credentialsId: 'ms-teams-webhook', variable: 'webhook_url')]) { + teamsWebHookURL = "$webhook_url" + } +} + pipeline { agent { label 'standard' } @@ -42,6 +54,18 @@ pipeline { overrideIndexTriggers(false) timeout(time: 3, unit: 'HOURS') buildDiscarder(logRotator(daysToKeepStr: '14', artifactDaysToKeepStr: '14')) + office365ConnectorWebhooks([[ + name : "Corda 4 Jenkins Connector", + notifyBackToNormal : true, + startNotification : false, + notifyFailure : true, + notifySuccess : true, + notifyNotBuilt : false, + notifyAborted : false, + notifyRepeatedFailure: true, + notifyUnstable : true, + url : "${teamsWebHookURL}" + ]]) } parameters { diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 96abe97cfa..e8543c7ab5 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -7,6 +7,7 @@ /** * Sense environment */ +boolean isReleaseBranch = (env.BRANCH_NAME =~ /^release\/os\/.*/) boolean isReleaseTag = (env.TAG_NAME =~ /^release-.*(? Date: Tue, 15 Mar 2022 07:58:58 +0000 Subject: [PATCH 21/28] INFRA-1735 Teams notification's for C4 (#7107) * INFRA-1728 set correct java version for JDK 11 base image --- .ci/dev/compatibility/DockerfileJDK11 | 2 +- .ci/dev/publish-branch/Jenkinsfile.nightly | 24 ++++++++++++++++++++++ .ci/dev/regression/Jenkinsfile | 24 ++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/.ci/dev/compatibility/DockerfileJDK11 b/.ci/dev/compatibility/DockerfileJDK11 index 263c42a391..ff6eeaac95 100644 --- a/.ci/dev/compatibility/DockerfileJDK11 +++ b/.ci/dev/compatibility/DockerfileJDK11 @@ -1,4 +1,4 @@ -FROM azul/zulu-openjdk:11 +FROM azul/zulu-openjdk:11.0.14 RUN apt-get update && apt-get install -y curl apt-transport-https \ ca-certificates \ curl \ diff --git a/.ci/dev/publish-branch/Jenkinsfile.nightly b/.ci/dev/publish-branch/Jenkinsfile.nightly index b7b36f7eb8..0f38bf9cca 100644 --- a/.ci/dev/publish-branch/Jenkinsfile.nightly +++ b/.ci/dev/publish-branch/Jenkinsfile.nightly @@ -33,6 +33,18 @@ def nexusIqStageChoices = [nexusDefaultIqStage].plus( 'operate' ].minus([nexusDefaultIqStage])) +/** + * define an empty teamsWebHookURL and if it is a Release Branch + * then set it for the Corda 4 Jenkins Connector + */ +boolean isReleaseBranch = (env.BRANCH_NAME =~ /^release\/os\/.*/) +def teamsWebHookURL = "" +if (isReleaseBranch){ + withCredentials([string(credentialsId: 'ms-teams-webhook', variable: 'webhook_url')]) { + teamsWebHookURL = "$webhook_url" + } +} + pipeline { agent { label 'standard' } @@ -42,6 +54,18 @@ pipeline { overrideIndexTriggers(false) timeout(time: 3, unit: 'HOURS') buildDiscarder(logRotator(daysToKeepStr: '14', artifactDaysToKeepStr: '14')) + office365ConnectorWebhooks([[ + name : "Corda 4 Jenkins Connector", + notifyBackToNormal : true, + startNotification : false, + notifyFailure : true, + notifySuccess : true, + notifyNotBuilt : false, + notifyAborted : false, + notifyRepeatedFailure: true, + notifyUnstable : true, + url : "${teamsWebHookURL}" + ]]) } parameters { diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 96abe97cfa..e8543c7ab5 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -7,6 +7,7 @@ /** * Sense environment */ +boolean isReleaseBranch = (env.BRANCH_NAME =~ /^release\/os\/.*/) boolean isReleaseTag = (env.TAG_NAME =~ /^release-.*(? Date: Tue, 15 Mar 2022 09:00:21 +0000 Subject: [PATCH 22/28] ENT-6728: Archiving of a legal identity now done in its own txn, to cope with clustered notary nodes that have common legal identities between nodes (the service name one is common) --- .../node/services/api/IdentityServiceInternal.kt | 2 ++ .../services/identity/PersistentIdentityService.kt | 2 +- .../services/network/PersistentNetworkMapCache.kt | 12 ++++-------- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/node/src/main/kotlin/net/corda/node/services/api/IdentityServiceInternal.kt b/node/src/main/kotlin/net/corda/node/services/api/IdentityServiceInternal.kt index c77e39cec0..2bed926da5 100644 --- a/node/src/main/kotlin/net/corda/node/services/api/IdentityServiceInternal.kt +++ b/node/src/main/kotlin/net/corda/node/services/api/IdentityServiceInternal.kt @@ -15,4 +15,6 @@ interface IdentityServiceInternal : IdentityService { fun verifyAndRegisterNewRandomIdentity(identity: PartyAndCertificate) fun invalidateCaches(name: CordaX500Name) {} + + fun archiveNamedIdentity(name:String, publicKeyHash: String?) {} } \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt b/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt index fb0137fbe2..2e10525141 100644 --- a/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt +++ b/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt @@ -378,7 +378,7 @@ class PersistentIdentityService(cacheFactory: NamedCacheFactory) : SingletonSeri return resultList.last().publicKeyHash } - private fun archiveNamedIdentity(name:String, publicKeyHash: String?) { + override fun archiveNamedIdentity(name:String, publicKeyHash: String?) { archiveIdentityExecutor.submit { database.transaction { val deleteQuery = session.criteriaBuilder.createCriteriaDelete(PersistentNetworkMapCache.PersistentPartyToPublicKeyHash::class.java) diff --git a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt index eb79a58302..2749f83c5d 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt @@ -310,7 +310,7 @@ open class PersistentNetworkMapCache(cacheFactory: NamedCacheFactory, synchronized(_changed) { database.transaction { removeInfoDB(session, node) - archiveNamedIdentity(session, node) + archiveNamedIdentity(node) changePublisher.onNext(MapChange.Removed(node)) } } @@ -319,13 +319,9 @@ open class PersistentNetworkMapCache(cacheFactory: NamedCacheFactory, logger.debug { "Done removing node with info: $node" } } - private fun archiveNamedIdentity(session: Session, nodeInfo: NodeInfo) { + private fun archiveNamedIdentity(nodeInfo: NodeInfo) { nodeInfo.legalIdentities.forEach { party -> - val deleteQuery = session.criteriaBuilder.createCriteriaDelete(PersistentPartyToPublicKeyHash::class.java) - val queryRoot = deleteQuery.from(PersistentPartyToPublicKeyHash::class.java) - deleteQuery.where(session.criteriaBuilder.equal(queryRoot.get("name"), party.name.toString())) - session.createQuery(deleteQuery).executeUpdate() - session.save(PersistentPartyToPublicKeyHash(party.name.toString(), party.owningKey.toStringShort() )) + identityService.archiveNamedIdentity(party.name.toString(), party.owningKey.toStringShort()) } } @@ -457,7 +453,7 @@ open class PersistentNetworkMapCache(cacheFactory: NamedCacheFactory, logger.debug { "Number of node infos to be cleared: ${result.size}" } for (nodeInfo in result) { session.remove(nodeInfo) - archiveNamedIdentity(session, nodeInfo.toNodeInfo()) + archiveNamedIdentity(nodeInfo.toNodeInfo()) } } } From 95726b5d5887f9f2cfbdca49ec997de315ddefe5 Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Wed, 16 Mar 2022 12:43:48 +0000 Subject: [PATCH 23/28] ENT-6699 update java version --- docker/src/docker/Dockerfile | 3 ++- docker/src/docker/Dockerfile-debug | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docker/src/docker/Dockerfile b/docker/src/docker/Dockerfile index d3d287a750..7ea91f52ec 100644 --- a/docker/src/docker/Dockerfile +++ b/docker/src/docker/Dockerfile @@ -1,7 +1,8 @@ -FROM azul/zulu-openjdk:8u192 +FROM azul/zulu-openjdk:8u312 ## Add packages, clean cache, create dirs, create corda user and change ownership RUN apt-get update && \ + apt-mark hold zulu8-jdk && \ apt-get -y upgrade && \ apt-get -y install bash curl unzip && \ rm -rf /var/lib/apt/lists/* && \ diff --git a/docker/src/docker/Dockerfile-debug b/docker/src/docker/Dockerfile-debug index 5b0c7bbb1f..a1175c989c 100644 --- a/docker/src/docker/Dockerfile-debug +++ b/docker/src/docker/Dockerfile-debug @@ -1,7 +1,8 @@ -FROM azul/zulu-openjdk:8u192 +FROM azul/zulu-openjdk:8u312 ## Add packages, clean cache, create dirs, create corda user and change ownership RUN apt-get update && \ + apt-mark hold zulu8-jdk && \ apt-get -y upgrade && \ apt-get -y install bash curl unzip netstat lsof telnet netcat && \ rm -rf /var/lib/apt/lists/* && \ From d1adf3643dbb02fbac63fa054965399bc2476707 Mon Sep 17 00:00:00 2001 From: ConnelMcGovern Date: Tue, 22 Mar 2022 15:15:05 +0000 Subject: [PATCH 24/28] ENT-6716 Remove Corda OS image publishing to Docker hub for CE4.8.x patches and below --- .ci/dev/regression/Jenkinsfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 96abe97cfa..e595a206c0 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -10,6 +10,7 @@ boolean isReleaseTag = (env.TAG_NAME =~ /^release-.*(? Date: Tue, 22 Mar 2022 15:44:24 +0000 Subject: [PATCH 25/28] ENT-6716 Remove Corda OS image publishing to Docker hub for CE4.8.x patches and below --- .ci/dev/regression/Jenkinsfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index e8543c7ab5..28a1dca022 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -11,6 +11,7 @@ boolean isReleaseBranch = (env.BRANCH_NAME =~ /^release\/os\/.*/) boolean isReleaseTag = (env.TAG_NAME =~ /^release-.*(? Date: Wed, 30 Mar 2022 16:35:40 +0100 Subject: [PATCH 26/28] CORDA-4239: Regenerate test certificates with 10yr validity. --- .../internal/crypto/keystores/bridge_ec.jks | Bin 1163 -> 1162 bytes .../internal/crypto/keystores/bridge_rsa.jks | Bin 1804 -> 1804 bytes .../internal/crypto/keystores/float_ec.jks | Bin 1159 -> 1160 bytes .../internal/crypto/keystores/float_rsa.jks | Bin 1801 -> 1804 bytes .../internal/crypto/keystores/gencerts.sh | 40 ++++++++++++++++++ .../internal/crypto/keystores/trust.jks | Bin 501 -> 502 bytes 6 files changed, 40 insertions(+) create mode 100755 node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/gencerts.sh diff --git a/node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/bridge_ec.jks b/node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/bridge_ec.jks index 41bf8579a3b2698b972823800fa9d54737d2f4c6..f0a6921cff2767ab695f478ef30aa1e96519db64 100644 GIT binary patch delta 680 zcmeC??BbjtUtfPa<@ad@28McrS_3{dE^RhO7Dg>5K}JSa2A1qkjnP-mzm&GVDtX)F zUgq38t9A)=tTLXt#js|Q@vSq}%v;V(cei^nN%EGC*rYYn&SgGLIw9CywC3oSb8FA- z3vqlDrf_`yBGJYzg%Zz?v|IO|X)B+S%Ay{+*0rg0c}7~jSF)P6`7D=Gn;ij1q=9Z= zVqlHXGc~YeU|{@X(8Txyi03X~W@2PwV&SiwojLJjjI@!Ffw8fHp{b#%fl-t=uQ8Bo zWDem@c3{j%RbJt@>DKyN*^dJx_lOJh*`3_K!-C&>`{ARvEhWVsFhxtNTtpX2s<9%(C^^{BOX+#-Y{ban6>7nTeHw*@MBrl}VA|Rmy6n%lrPsvwh+J z{3f|ZW=&S2dq+_|n~3K+vq>ef-4;8iqxA0Me5JYt}Xk%xcR_`Iql~?G#I-9fPxjA delta 699 zcmeC;?B<*xU!T3{z`u9~28McrS_3{dE^RhO7Dg>5K}JSa2A1qIaa#HL6;rn+N1lCk zn2q6#@7ycLV^i}kpH9pb6T5$Q_l_$Dw-S$?&E~u_VWm;2{|}bPQ^mfOS*bt&KTfN) zSrX))`+8M{#jf={^}d7yfv(h+d8At65zJDD-%$K$2uL1&AJ7d< z46G4)rUsS_42=H_nizip@!SQ>OpHuSEEWsj)=s{_6eDeDX<%+(WN2h+YG4*6&TC|3 zU~FUo;ZAm7%t*c7v9xe|p0VhS<+-13@~jcscI(;Eh8fasm#>}B_*3#AM{8%yjI53- zO@s8K79r{Xq{0rLyL5i0<>}2~+>=-NKkQyyXpnCp&&C`otIQ%{Al4v~A0MlDvMHp| zN4#n~+w&7sq64Pyn9R#$RbQBO+J%GdpxDaxHP_f;cbMxFPF&VzuQ-;>9BdnoBe!Y%NqB2e{G)X)R_S`-|hpIEcVpdR{0T(J>;Q(!79i${ga%E{-9k=K(8$1o#>B+H z0x4*~+{yQtyeCg)mU8%fH-^RK#;h&kHzeX)pNR2t{&#$~XdzSRmrr-9{}=PI)gAIx zob=sWEdO2o0T#bC=N1G#w=B-zx2x`H`JdnW3v(yGWtOeS7A9z3cV{qgVNwV?&{bUH z(Prl~QPX^Sx1ZgA`E&m}PF|Wg-?RIHgUT9DCI#u;{ij6FuFKwR$?7GWbIqjPu0Oo~ lUh?_hbEPlqR2S$?e0?r|_Q$K!;%Baq+*9ef;>ra!9ROSD79Rir diff --git a/node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/bridge_rsa.jks b/node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/bridge_rsa.jks index d6828b23900ea0c1071d5179796952c38ace0a5e..87224d4727e13e635b4eb1d20c0a85eaa3d0e890 100644 GIT binary patch delta 1348 zcmeC->*1RqUtfPapCZ=r$d~96WY>X_7T1ptx zjAT;EjtTbuui9+#XS|8`>hIUB zTTd-n{+*-H;bVfOqG}{-{azo9e`1eA`%ho4$^IL@>G-L&X>6>#1>BG1o^$i@iQ1L8 z?f(+FpzK0n*3KIrcVxSqc$U|2d)cK0)3@@b9Ld)T`PJs2t^1zyZnskBfvek86H>#4 z!`uBLH_AFTx>`K@`|9B5HO1u~Hb!^n8P-=_s@kO`xOLU~yE{0;&-wZ5?}@6f^qSUf z?IgHr<-$Fz?-f^M-VHJMxoXShaN>R!3#pmCs(bnu8tHE~K3#uGPj=BGrwy!82ymhC%_tvrn0dhIt z7?K5ZOMNW%*ZCgu`C&3e>HS^D_PR;VN3Q%6DE=$Y#*#F<-Qq>Wa@EEy-;c2H?Ws6u zR(sB9!O5B7zZ+k-I5(K8UEch@ZKZ=!h1(P!(~WE!XD!-uNZnx8yxLdO5Ak-&z4h-u zBC)SAsotZ{+)umsOz(a^Cx%_0y(QnU{QcMZz|*XP!RAh~RPhV(^r?P{P7@bBS!Nkw zAzg8P{$+E4SdHVC6dtW?mR-vB;(^k=I}VlI-3-7q%)lC5@iwr}zT7AukO4$21~E4t>lzUa+g zuD0#W=C)6IlNYjyCZwM%`)g#EADbAzUU%v0Z9zM}Wm@iBrpvc)$MeUtY!{0&DOjGV zWK<8YQ!olp6iuDPv~%$)x4oP@h0N0xFGSwW>0A#FV#b}o;N1$ukQnUy(4 z1|FIwrk2Q|3F1ypWc8jb#wO+PAye?G!t~pd)L-eXxm6R}*uFPXO8>RUncLON+UB?T zzOuX~e(H;kK9_&zOsQDyPKj9dRVp}BXEHisB7`QSi zGQ3Jz&2)L+pLn(}{GZ<>*T}5NN_6ii%4ZYtTxT|^B=#GVf5F#9mQ||?7SBC; tro?5T|3gi0A%onao4-PhE=~EmbaMBW?|Em7uU}tvIprJI{_6(OI-i} delta 1363 zcmeC->*1RqU!T3{;L}b92BzHxO-$Pj_}I9#*%(vTWa`u-;9*D z6Gyl0_7Lq|am?nkgno~_U)lNmlNrY&S}t)3`={LX)MT+?UA*qOz<%);TPJgVz4>~N z{^g8-NuLj}=We@rLD%+5nDN{j@ABGY`wq`|YhFJkBQa;%!bH=0ledqZ7Sw#&Vtmp< zErjV2EGu2N#T>d&n;zF|?dDZ;&q_|OU$wU=(%ehv`M2L4r{A&c{^!onmG>dM zUoCz1y@bZ5v!YRUN#g$lzkimQkT3FXcNu@0W9O0ghdAUH#S>EfY>%@0qt~z9 z8S1vqwikV_`su3!n>S4IEBCg;vRQZC&1k4Y#rnnSof zR;_2^HPN$O2fl{~2_}3}U-IEq6^o%>(B~_gooBvhyZ@_JL?MUoy9*zf;pvRhiZRwwMe^?FNC z+?@1l0ZU!0{8y~lp1DP7Q-@HGN^yJTp7>hT;^S}je>Ih1varkw3p?E>HSd1N7xx>- z-|p&+eymfUAENf?V0L$A#i!Z7&cD~4vul6zyEiFE*D<9h{;xVPNn~00oVMWItQ%qt zwAUU@x@~8_rI_bL$ga2Bw0hH?9^I(W_-j&q!aXmQs|>(I%)lCMracH%9oU>(NW@2S9@G#^y;G8VM>>+JvX<%+(WN2h+W?&vA z&TC|3U~FUo;ZCk*&Z_Ud&{?$o;E|1640)4|j! zM6h~1>_As>jYpfE(?m`4>D_*I|K-p9?>KpB;(X8U2M#K0Jed@vclVzXJ-aS@vn8vS tY|b^4cDw%Y`g_Uef6tY^tW#Z}S2LlrJFjo%B?%!lzuS{sTIH3Rod8~#RLB4T diff --git a/node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/float_ec.jks b/node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/float_ec.jks index 7deeda8119daedc088bd444f31d0f83acc5a7eb5..bd7f2632260038e51f81b52a96be20eb1b8d9505 100644 GIT binary patch delta 673 zcmZqY?BJXrS6_cSmC=`hfuY`@)_{+VOPh_6g;9%1kdcvt|Gp*^HR&0UBm5jWFo3%H22v%T|V4%`P!wkr&2T@?UxVTf0KFD@AoO~ zwH4cZr{}t8EQ{Lu=jz_1|3$ktC>k+sik9E*pk!gW=Z)|_OFmA^y}j4Z)E_e6G;x_6 zi?OEOx5?+2Vx*0X42+Ep3{4G94UD72d5wWwBXbCMvOQyZ>VYuPx}N-7vLf&8Hs zb4aC3{}lEu(9nxdv8!Gz`h)6j@6|#4pY-|pd6l9KI&0K@G`+N?ZLbwJmlR2T?RHpP zXpnCp&&C`otIQ%{Al4w#6ccxR`uT^lrk67wu-u!>{Uz=W7YJu)s`1u?egZ> zToUYdOmMPMm%}Z|xBr+FD!i_7@AtM^#?>-n`^IR!sZ>gNS}y}@ zgr2E^B?ANFPJ<@Ktw0>PfQy-lk%@_gGd*l0C}3pZ0b^oni5xH>?&Ld6-jgRXOF4YV z6uhc1{q`jFS9)u1)xtpX2s;!%(C^^LIlm@9t;MqOo|MzQdTov-uEY-?F;|sH_0_JYqApE zJBsqzL_F7-O)81~#-!lT`%C(w-LYlWs)EIHkDe)US?K>z(_6?Ox9H}tP@_vzBrG2J XUf(4B#mpw}5K}JSa2A1qr?)O?7j;5V{y7G$O zh6Mtzy?rA8J57JS;@>=ao2r}WfOmxtEN za(EYgFgE&kKf+XVhQX70Z<7BnY37gE!50{3zcbc(#n+x={lQx~w;p~Z^7DWDl#>&e z$+4ups&$`yjwwdk(9*!%z{t?Z)Xc~{N}Sio$iUdh0>Yha&zPS2qg!R6oOb?l_9P|O zS4Lk$-WxII`1o%xNQ_c(^6lGmHS**;Z>hcU_hN%i2$t9ySiGHji_*EX+)-49xBf1};nrX1zI1F5jAVH@Mz^m?9Wo zeel-H6t!o^!bDPh7^9UU{FoH9p8YB+H0x4j?+{t&CyeCg& zmU8%fH-^RK#;h&kHzeX)pNR2t{&#$~XdzSRmrr-9{}=PI)gAIxob=sWEdO2o0T#bC z=N1G#w=B-zx2x`H`JdnW3v(yGW|pnT79vTTP^S|dxU)HHE&^x&Dd#>Pg Tfe3}Ft9;vd@5blO{vZtiM6MEz diff --git a/node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/float_rsa.jks b/node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/float_rsa.jks index 6eddf4d4b1fbed139e7f448c80d41fb5f518de2e..737826a534623079e5a01d88267505c85d564754 100644 GIT binary patch delta 1309 zcmZwDeLT|%0LSs|w+D}z$2^Zq>5N!IPBJ3dPEvX$ zHb4hJj1#e4Rt5Mk zJhD!%3#N)SCX<@OHr+&ak2ex68bWK*SuQlxO}aXcXOV4`@ksYjfLWYosRiaCv0l=y z&|fJE^4=t~6 zNpN(tvr%6kRv2p==a69bG@LWB^2LVj)zQ9SbS0Ko*lwf}4z>BQR>w!A;>j^nM_h z9n>B-S|WA=el7Lo>QodZc4$hKx!`jpn&-%8avjf1a*r=}UP_fL_*0TlcV1kXehi}9 zH-`i=TIY1%3G$hk1P$ac|16UYq*sg&-|8#ppyn_2bzMki^{PI76rGcqSONj>>Wbg&zS$k`MloIE`Z)<6|0bRc z(NS*DZwLZd_1e3}QZN{;OEUpln4z7EZb~1U+F!}Cs%eFHt*}(>*X=dfK-p4=k zlnUH#!eM*dT62a-GcoWkH(cAM_gTNbv?m0ZuvGTk`7?`0jVZF#OPpUy2;P7DsF8$K zPjOCpGecvi8ltJm$l?yHtM`$I20}i`K;Dk@~%n2ml2`kYM-#;2YSu&trg9 z`n*O?E8i5k%|Trl|A9w$a(GLPBJ3MQP_(R~$aMJA2zkA{tuNZ1vm0qA>h zb<4e3#El(l7%IZq9q$Q)!CUYQ_>Iqt)Tu=PZ~#DR9o{GUVruoDshhj!|4qLnq>l)K zjL;Uossw`}TaKK)amrcvG?SX0-xg`%qA>20pBCiRoDH7x95(Hpb8^uRDd1U99Sh8; z8jb5Sd1J0asOnNzwXgw7LR*7hBl-ICse_jR+3l4W^c-eZ8JlS(JaQoL+{xo;WAfE4 z>=fz(VC&0NTS|#tg3}uelB+uVQg-k|#vFnS@ku8~)Zv7|QVJmer}kVU*f=ARVDoiF JmV9S8@gMxzP&fbp delta 1348 zcmeC->*SjtSD(G|hkOcANaTM*4z} zljR~t7U`8gGw%z>h(5pky*^ri_e|c!+w08l+)(F!EVb;^>?F^l|5p{dHYs(#eAOcR z-RI$sU7@`kSGFa0Z9U4p_0;}$(WmYFtK^(FyGSo_*S#F{H`R0MqV{D@S2)Y-#aFmA z&rMmLb7ty{7LM%Cb)UHpKGxr-qb@v;{a1`+&+;$4+n&ZKY)$#1u=dF7{@IKB>t9Mm z%zfK-A#~2ox)UEx3wd=_&weXu+}%H4=Pip~n!nvwN4~ks3U)*uPszFOzgKp0=H!jf zJ=XB`%%0sC%5u`@YRonD9&L_H!_5tkpGop;t!KWrKPl0U+vVR2@8*g-*A^wdYw%j8 zsq-P!$8whH2IHpx?l(+p0=k@R-P=;Q{+iW$G3-85dg9kZ>zZAAj&`Nk&5GV_DWlhR z;n0@yHhH@{*G;}2Z!A~#FzP;Xe(kxb>mPW>RV2ty{IggxSHs(hi~VWwf6=hn%XS6t zcCpDNm93mvj{nNb zdf8pX%IdR?>@RAU=8DR3{0NPht6e0zYJbY?u(GQK#RmTMJ321kz3^_*o_xiR%YM(B zcskeWgQny2*kiS9n>+r!HWxiG=a1jRU`4sFn;C#fn1MAy&(y#Y$Z`fIW_yDs#>Weo znHZUvSmeI5(NW@2S9@G#^y;ACT-EXC|5ZD}{&5|9XBg|8r71nu(c_fpKx6 zLB4@J8*`|vGK++PSc6D@e5~ThrjSM-@v7}?&reK=4w$}UavzJ8NTJ)=J3s&4ZI)?L z?*7_3^+$Ng*8a&0*hG>Pa@*N_|0)Mw>*#h&I>9sB&_i1A)QcCznUhs?msfu3JH@2P z@Ixi;`_u29ZPRBli_G*tAv|eAR&c`lH46?r4Rh~xezg`J%8WaJA-n~MBcY+3bGMLl zG7EEz3@kiNObjfL!V}D$oWSZmS(Hu6;q%=X7MB~dwus-5h;Mx&#>@HN@!6td1>N&&+Z2fDr-EM6r^|epAtR0E_<^j wtCwufHIsI`{_y&H$>)F1mA root.pem +keytool -importcert -noprompt -file root.pem -alias root -keystore trust.jks -storepass trustpass + +# Create a chain for EC Bridge +keytool -certreq -alias bridgecert -keystore bridge_ec.jks -storepass bridgepass -keypass bridgepass |keytool -gencert -validity 3650 -ext ku:c=dig,keyEncipherment -ext: eku:true=serverAuth,clientAuth -rfc -keystore floatca.jks -alias floatroot -storepass capass -keypass cakeypass > bridge_ec.pem +cat root.pem bridge_ec.pem >> bridgechain_ec.pem +keytool -importcert -noprompt -file bridgechain_ec.pem -alias bridgecert -keystore bridge_ec.jks -storepass bridgepass -keypass bridgepass + +# Create a chain for RSA Bridge +keytool -certreq -alias bridgecert -keystore bridge_rsa.jks -storepass bridgepass -keypass bridgepass |keytool -gencert -validity 3650 -ext ku:c=dig,keyEncipherment -ext: eku:true=serverAuth,clientAuth -rfc -keystore floatca.jks -alias floatroot -storepass capass -keypass cakeypass > bridge_rsa.pem +cat root.pem bridge_rsa.pem >> bridgechain_rsa.pem +keytool -importcert -noprompt -file bridgechain_rsa.pem -alias bridgecert -keystore bridge_rsa.jks -storepass bridgepass -keypass bridgepass + +# Create a chain for EC Float +keytool -certreq -alias floatcert -keystore float_ec.jks -storepass floatpass -keypass floatpass |keytool -gencert -validity 3650 -ext ku:c=dig,keyEncipherment -ext: eku::true=serverAuth,clientAuth -rfc -keystore floatca.jks -alias floatroot -storepass capass -keypass cakeypass > float_ec.pem +cat root.pem float_ec.pem >> floatchain_ec.pem +keytool -importcert -noprompt -file floatchain_ec.pem -alias floatcert -keystore float_ec.jks -storepass floatpass -keypass floatpass + +# Create a chain for RSA Float +keytool -certreq -alias floatcert -keystore float_rsa.jks -storepass floatpass -keypass floatpass |keytool -gencert -validity 3650 -ext ku:c=dig,keyEncipherment -ext: eku::true=serverAuth,clientAuth -rfc -keystore floatca.jks -alias floatroot -storepass capass -keypass cakeypass > float_rsa.pem +cat root.pem float_rsa.pem >> floatchain_rsa.pem +keytool -importcert -noprompt -file floatchain_rsa.pem -alias floatcert -keystore float_rsa.jks -storepass floatpass -keypass floatpass diff --git a/node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/trust.jks b/node-api/src/test/resources/net/corda/nodeapi/internal/crypto/keystores/trust.jks index ea5b53b445c8f8ac4e2faba5a546b24e3a9ed69c..1252f7002a7c6a130c76ac3be08322e7eecdcb05 100644 GIT binary patch delta 279 zcmV+y0qFkq1NH-u86$t&Wccd<1z0XMFgXAK0l6@O0ktrK0a>5}0s#U71PNzWv5`Dn z95OO6GczzTH8C_bIa(JDGcqtUGB+_bF*G$fT9Haik^dS%@M#g%AeY;cC+aS&+I(Gs zhrL-EFY6S{+k2*lpM*{7Io21-^eit5Pl=ftT`P$gT?eWpe3{`h)dilEGy1HklUV^B ze}Y_I$CuCH9W~Qv-~`^23;bJMjxY=c2r7n1&OHPJ0tEmANB}TJ0wDnEWUB(xzWiSX z^bhmwV|*N}YGFr+a&HC{Nv<}MbY1oWAV7`!8__<-rh6q3bDhP^bVQ*~;VDZJFl}<# d`c*R0lo}cPH5}0s#U71Z>@L36VTp z95FdCH!w0WGBh+WI9eACGBPkTGB`0ZG&C?cT9Haik^dS%^W9toMA(|N7uXnIh2$0u z3I9RnqM-s+^zz($|8ouoe!@*5lJ`p%Z|;A<1Wv5Zpi<{Kb8o)7e&u)k`@eB*lUV^B ze{Wx1A<2SNflL>Aw+83Plv_}jxG)R`2r7n1&OHPJ0tEmAM*uKH0w7kvigSEOhCV`( zDL0pkPCox1&i{zX(vhD@i{L;ctVseO8@rFn70s?|vpEGy9c Date: Thu, 31 Mar 2022 16:21:23 +0100 Subject: [PATCH 27/28] NOTICK: Fixed merge typo. --- .../kotlin/net/corda/core/internal/PlatformVersionSwitches.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt b/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt index c21a830ca9..3628c05526 100644 --- a/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt +++ b/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt @@ -16,7 +16,6 @@ object PlatformVersionSwitches { const val LIMIT_KEYS_IN_SIGNATURE_CONSTRAINTS = 5 const val BATCH_DOWNLOAD_COUNTERPARTY_BACKCHAIN = 6 const val ENABLE_P2P_COMPRESSION = 7 - const val RESTRICTED_DATABASE_OPERATIONS = 7 const val CERTIFICATE_ROTATION = 9 const val RESTRICTED_DATABASE_OPERATIONS = 7 } \ No newline at end of file From 05eb5103531d4d6dc636a7d7313920fc2c51b431 Mon Sep 17 00:00:00 2001 From: Adel El-Beik Date: Thu, 31 Mar 2022 16:27:52 +0100 Subject: [PATCH 28/28] NOTICK: Fixed merge change. --- .../kotlin/net/corda/core/internal/PlatformVersionSwitches.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt b/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt index 3628c05526..c6d93f272f 100644 --- a/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt +++ b/core/src/main/kotlin/net/corda/core/internal/PlatformVersionSwitches.kt @@ -16,6 +16,6 @@ object PlatformVersionSwitches { const val LIMIT_KEYS_IN_SIGNATURE_CONSTRAINTS = 5 const val BATCH_DOWNLOAD_COUNTERPARTY_BACKCHAIN = 6 const val ENABLE_P2P_COMPRESSION = 7 - const val CERTIFICATE_ROTATION = 9 const val RESTRICTED_DATABASE_OPERATIONS = 7 + const val CERTIFICATE_ROTATION = 9 } \ No newline at end of file