From cd8cd60a0fd943198a87d266bd15b807eeaa20ba Mon Sep 17 00:00:00 2001 From: nargas-ritu Date: Thu, 17 Feb 2022 10:43:34 +0000 Subject: [PATCH 01/93] NOTICK: Changes done while creating a new branch for Corda 4.10 --- .../src/main/kotlin/net/corda/common/logging/Constants.kt | 2 +- constants.properties | 2 +- docker/src/bash/example-mini-network.sh | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/logging/src/main/kotlin/net/corda/common/logging/Constants.kt b/common/logging/src/main/kotlin/net/corda/common/logging/Constants.kt index 49cc02b4bc..603a0132e3 100644 --- a/common/logging/src/main/kotlin/net/corda/common/logging/Constants.kt +++ b/common/logging/src/main/kotlin/net/corda/common/logging/Constants.kt @@ -9,4 +9,4 @@ package net.corda.common.logging * (originally added to source control for ease of use) */ -internal const val CURRENT_MAJOR_RELEASE = "4.9-SNAPSHOT" +internal const val CURRENT_MAJOR_RELEASE = "4.10-SNAPSHOT" diff --git a/constants.properties b/constants.properties index 44f83464ee..a03fdd7191 100644 --- a/constants.properties +++ b/constants.properties @@ -2,7 +2,7 @@ # because some versions here need to be matched by app authors in # their own projects. So don't get fancy with syntax! -cordaVersion=4.9 +cordaVersion=4.10 versionSuffix=SNAPSHOT gradlePluginsVersion=5.0.12 kotlinVersion=1.2.71 diff --git a/docker/src/bash/example-mini-network.sh b/docker/src/bash/example-mini-network.sh index 4f25988ccd..85a2b450e6 100755 --- a/docker/src/bash/example-mini-network.sh +++ b/docker/src/bash/example-mini-network.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash NODE_LIST=("dockerNode1" "dockerNode2" "dockerNode3") NETWORK_NAME=mininet -CORDAPP_VERSION="4.9-SNAPSHOT" -DOCKER_IMAGE_VERSION="corda-zulu-4.9-snapshot" +CORDAPP_VERSION="4.10-SNAPSHOT" +DOCKER_IMAGE_VERSION="corda-zulu-4.10-snapshot" mkdir cordapps rm -f cordapps/* From 59272e880db9d4e3e3405115ad32b7fdc294fd1d Mon Sep 17 00:00:00 2001 From: Chris Cochrane <78791827+chriscochrane@users.noreply.github.com> Date: Tue, 22 Feb 2022 18:09:30 +0000 Subject: [PATCH 02/93] ENT-6607 moved all 3rd party lib versions to constants.properties (#7077) * ENT-6607 moved all 3rd party lib versions to constants.properties * Post-review - Corrected Corda version number --- build.gradle | 108 ++++++++++++++++++++----------------------- constants.properties | 64 +++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 58 deletions(-) diff --git a/build.gradle b/build.gradle index 3574d0ac8d..177c336f05 100644 --- a/build.gradle +++ b/build.gradle @@ -56,20 +56,17 @@ buildscript { 'org.opentest4j**' ] - // gradle-capsule-plugin:1.0.2 contains capsule:1.0.1 by default. - // We must configure it manually to use the latest capsule version. - ext.capsule_version = '1.0.3' + ext.capsule_version = constants.getProperty("capsuleVersion") - 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.jetty_version = '9.4.19.v20190610' - ext.jersey_version = '2.25' - ext.servlet_version = '4.0.1' - ext.assertj_version = '3.12.2' - ext.slf4j_version = '1.7.30' - ext.log4j_version = '2.17.1' + ext.asm_version = constants.getProperty("asmVersion") + ext.artemis_version = constants.getProperty("artemisVersion") + ext.jackson_version = constants.getProperty("jacksonVersion") + ext.jetty_version = constants.getProperty("jettyVersion") + ext.jersey_version = constants.getProperty("jerseyVersion") + ext.servlet_version = constants.getProperty("servletVersion") + ext.assertj_version = constants.getProperty("assertjVersion") + ext.slf4j_version = constants.getProperty("slf4JVersion") + ext.log4j_version = constants.getProperty("log4JVersion") ext.bouncycastle_version = constants.getProperty("bouncycastleVersion") ext.guava_version = constants.getProperty("guavaVersion") ext.caffeine_version = constants.getProperty("caffeineVersion") @@ -78,63 +75,58 @@ buildscript { ext.metrics_new_relic_version = constants.getProperty("metricsNewRelicVersion") ext.djvm_version = constants.getProperty("djvmVersion") ext.deterministic_rt_version = constants.getProperty('deterministicRtVersion') - ext.okhttp_version = '3.14.2' - ext.netty_version = '4.1.68.Final' + ext.okhttp_version = constants.getProperty("okhttpVersion") + ext.netty_version = constants.getProperty("nettyVersion") ext.tcnative_version = constants.getProperty("tcnativeVersion") ext.typesafe_config_version = constants.getProperty("typesafeConfigVersion") - ext.fileupload_version = '1.4' - ext.kryo_version = '4.0.2' - ext.kryo_serializer_version = '0.43' - // Legacy JUnit 4 version - ext.junit_version = '4.12' - // Need this version to access classpath scanning error handling fix - - // see https://github.com/junit-team/junit5/commit/389de48c2a18c5a93a7203ef424aa47a8a835a74 - // Upgrade to 5.5.x when GA release is available. - ext.junit_vintage_version = '5.5.0-RC1' - ext.junit_jupiter_version = '5.5.0-RC1' - ext.junit_platform_version = '1.5.0-RC1' - ext.mockito_version = '2.28.2' - ext.mockito_kotlin_version = '1.6.0' - ext.hamkrest_version = '1.7.0.0' - ext.jopt_simple_version = '5.0.2' - ext.jansi_version = '1.18' - ext.hibernate_version = '5.4.3.Final' - ext.h2_version = '1.4.199' // Update docs if renamed or removed. - ext.rxjava_version = '1.3.8' - ext.dokka_version = '0.9.17' - ext.eddsa_version = '0.3.0' - ext.dependency_checker_version = '5.2.0' - ext.commons_collections_version = '4.3' - ext.beanutils_version = '1.9.4' + ext.fileupload_version = constants.getProperty("fileuploadVersion") + ext.kryo_version = constants.getProperty("kryoVersion") + ext.kryo_serializer_version = constants.getProperty("kryoSerializerVersion") + ext.junit_version = constants.getProperty("junitVersion") + ext.junit_vintage_version = constants.getProperty("junitVintageVersion") + ext.junit_jupiter_version = constants.getProperty("junitJupiterVersion") + ext.junit_platform_version = constants.getProperty("junitPlatformVersion") + ext.mockito_version = constants.getProperty("mockitoVersion") + ext.mockito_kotlin_version = constants.getProperty("mockitoKotlinVersion") + ext.hamkrest_version = constants.getProperty("hamkrestVersion") + ext.jopt_simple_version = constants.getProperty("joptSimpleVersion") + ext.jansi_version = constants.getProperty("jansiVersion") + ext.hibernate_version = constants.getProperty("hibernateVersion") + ext.h2_version = constants.getProperty("h2Version") + ext.rxjava_version = constants.getProperty("rxjavaVersion") + ext.dokka_version = constants.getProperty("dokkaVersion") + ext.eddsa_version = constants.getProperty("eddsaVersion") + ext.dependency_checker_version = constants.getProperty("dependencyCheckerVersion") + ext.commons_collections_version = constants.getProperty("commonsCollectionsVersion") + ext.beanutils_version = constants.getProperty("beanutilsVersion") ext.jsr305_version = constants.getProperty("jsr305Version") - ext.shiro_version = '1.4.1' + ext.shiro_version = constants.getProperty("shiroVersion") ext.artifactory_plugin_version = constants.getProperty('artifactoryPluginVersion') - ext.hikari_version = '3.3.1' - ext.liquibase_version = '3.6.3' + ext.hikari_version = constants.getProperty("hikariVersion") + ext.liquibase_version = constants.getProperty("liquibaseVersion") ext.artifactory_contextUrl = 'https://software.r3.com/artifactory' ext.snake_yaml_version = constants.getProperty('snakeYamlVersion') - ext.docker_compose_rule_version = '1.5.0' - ext.selenium_version = '3.141.59' - ext.ghostdriver_version = '2.1.0' + ext.docker_compose_rule_version = constants.getProperty("dockerComposeRuleVersion") + ext.selenium_version = constants.getProperty("seleniumVersion") + ext.ghostdriver_version = constants.getProperty("ghostdriverVersion") ext.proguard_version = constants.getProperty('proguardVersion') - ext.jsch_version = '0.1.55' - ext.protonj_version = '0.33.0' // Overide Artemis version - ext.snappy_version = '0.4' + ext.jsch_version = constants.getProperty("jschVersion") + ext.protonj_version = constants.getProperty("protonjVersion") + ext.snappy_version = constants.getProperty("snappyVersion") ext.class_graph_version = constants.getProperty('classgraphVersion') - ext.jcabi_manifests_version = '1.1' - ext.picocli_version = '3.9.6' - ext.commons_lang_version = '3.9' - ext.commons_io_version = '2.6' - ext.controlsfx_version = '8.40.15' + ext.jcabi_manifests_version = constants.getProperty("jcabiManifestsVersion") + ext.picocli_version = constants.getProperty("picocliVersion") + ext.commons_lang_version = constants.getProperty("commonsLangVersion") + ext.commons_io_version = constants.getProperty("commonsIoVersion") + ext.controlsfx_version = constants.getProperty("controlsfxVersion") ext.detekt_version = constants.getProperty('detektVersion') ext.docker_java_version = constants.getProperty("dockerJavaVersion") if (JavaVersion.current().isJava8()) { - ext.fontawesomefx_commons_version = '8.15' - ext.fontawesomefx_fontawesome_version = '4.7.0-5' + ext.fontawesomefx_commons_version = constants.getProperty("fontawesomefxCommonsJava8Version") + ext.fontawesomefx_fontawesome_version = constants.getProperty("fontawesomefxFontawesomeJava8Version") } else { - // has been compiled by a more recent version of the Java Runtime (class file version 55.0) - ext.fontawesomefx_commons_version = '11.0' - ext.fontawesomefx_fontawesome_version = '4.7.0-11' + ext.fontawesomefx_commons_version = constants.getProperty("fontawesomefxCommonsVersion") + ext.fontawesomefx_fontawesome_version = constants.getProperty("fontawesomefxFontawesomeVersion") } // Name of the IntelliJ SDK created for the deterministic Java rt.jar. diff --git a/constants.properties b/constants.properties index a03fdd7191..e980b0acf2 100644 --- a/constants.properties +++ b/constants.properties @@ -37,3 +37,67 @@ openSourceSamplesBranch=https://github.com/corda/samples/blob/release-V4 jolokiaAgentVersion=1.6.1 detektVersion=1.0.1 tcnativeVersion=2.0.48.Final + +# ENT-6607 all third party version in here now + +# gradle-capsule-plugin:1.0.2 contains capsule:1.0.1 by default. +# We must configure it manually to use the latest capsule version. +capsuleVersion=1.0.3 +asmVersion=7.1 +artemisVersion=2.19.1 +# TODO Upgrade Jackson only when corda is using kotlin 1.3.10 +jacksonVersion=2.9.7 +jettyVersion=9.4.19.v20190610 +jerseyVersion=2.25 +servletVersion=4.0.1 +assertjVersion=3.12.2 +slf4JVersion=1.7.30 +log4JVersion=2.17.1 +okhttpVersion=3.14.2 +nettyVersion=4.1.68.Final +fileuploadVersion=1.4 +kryoVersion=4.0.2 +kryoSerializerVersion=0.43 +# Legacy JUnit 4 version +junitVersion=4.12 +# Need this version to access classpath scanning error handling fix - +# see https://github.com/junit-team/junit5/commit/389de48c2a18c5a93a7203ef424aa47a8a835a74 +# Upgrade to 5.5.x when GA release is available. +junitVintageVersion=5.5.0-RC1 +junitJupiterVersion=5.5.0-RC1 +junitPlatformVersion=1.5.0-RC1 +mockitoVersion=2.28.2 +mockitoKotlinVersion=1.6.0 +hamkrestVersion=1.7.0.0 +joptSimpleVersion=5.0.2 +jansiVersion=1.18 +hibernateVersion=5.4.3.Final +# h2Version - Update docs if renamed or removed. +h2Version=1.4.199 +rxjavaVersion=1.3.8 +dokkaVersion=0.9.17 +eddsaVersion=0.3.0 +dependencyCheckerVersion=5.2.0 +commonsCollectionsVersion=4.3 +beanutilsVersion=1.9.4 +shiroVersion=1.4.1 +hikariVersion=3.3.1 +liquibaseVersion=3.6.3 +dockerComposeRuleVersion=1.5.0 +seleniumVersion=3.141.59 +ghostdriverVersion=2.1.0 +jschVersion=0.1.55 +# Override Artemis version +protonjVersion=0.33.0 +snappyVersion=0.4 +jcabiManifestsVersion=1.1 +picocliVersion=3.9.6 +commonsLangVersion=3.9 +commonsIoVersion=2.6 +controlsfxVersion=8.40.15 +# FontAwesomeFX for Java8 +fontawesomefxCommonsJava8Version=8.15 +fontawesomefxFontawesomeJava8Version=4.7.0-5 +# FontAwesomeFX for a more recent version of the Java Runtime (class file version 55.0) +fontawesomefxCommonsVersion=11.0 +fontawesomefxFontawesomeVersion=4.7.0-11 From 3f94ed66d4e0fc42a4487791ab6fa37faf9798dd Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Thu, 24 Feb 2022 09:35:31 +0000 Subject: [PATCH 03/93] ENT-6609 update docker images (#7086) --- docker/src/docker/Dockerfile | 1 + docker/src/docker/DockerfileAL | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/src/docker/Dockerfile b/docker/src/docker/Dockerfile index 41be49ad20..84200d542b 100644 --- a/docker/src/docker/Dockerfile +++ b/docker/src/docker/Dockerfile @@ -2,6 +2,7 @@ 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/DockerfileAL b/docker/src/docker/DockerfileAL index f3c8496604..8c5ccd46ff 100644 --- a/docker/src/docker/DockerfileAL +++ b/docker/src/docker/DockerfileAL @@ -1,11 +1,10 @@ -FROM amazonlinux:2 +FROM amazoncorretto:8u312-al2 ## Add packages, clean cache, create dirs, create corda user and change ownership -RUN amazon-linux-extras enable corretto8 && \ - yum -y install java-1.8.0-amazon-corretto-devel && \ - yum -y install bash && \ +RUN yum -y install bash && \ yum -y install curl && \ yum -y install unzip && \ + yum -y install shadow-utils.x86_64 && \ yum clean all && \ rm -rf /var/cache/yum && \ mkdir -p /opt/corda/cordapps && \ From 38988527b93d9608559e591d41dbb79bd73bdf03 Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Thu, 24 Feb 2022 10:36:06 +0000 Subject: [PATCH 04/93] ENT-6609 update docker images so repo for community edition is corda/community (#7089) --- .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 aa22fce3f3..82d0f66399 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -319,7 +319,7 @@ pipeline { './gradlew', COMMON_GRADLE_PARAMS, 'docker:pushDockerImage', - '-Pdocker.image.repository=corda/corda', + '-Pdocker.image.repository=corda/community', '--image OFFICIAL' ].join(' ') } From 5d734be8072d0447b1b6feb88fcfc0d439ecf7f8 Mon Sep 17 00:00:00 2001 From: "rick.parker" Date: Fri, 25 Feb 2022 13:29:20 +0000 Subject: [PATCH 05/93] ENT-6498 Fix API docs dependencies (bump dokka version missed from conflict resolution). --- constants.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constants.properties b/constants.properties index e980b0acf2..94dad22d7c 100644 --- a/constants.properties +++ b/constants.properties @@ -75,7 +75,7 @@ hibernateVersion=5.4.3.Final # h2Version - Update docs if renamed or removed. h2Version=1.4.199 rxjavaVersion=1.3.8 -dokkaVersion=0.9.17 +dokkaVersion=0.10.1 eddsaVersion=0.3.0 dependencyCheckerVersion=5.2.0 commonsCollectionsVersion=4.3 From 4fe68c93f4f5176a4a03bf3c73d43e8c672be9a3 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Tue, 8 Mar 2022 12:04:26 +0000 Subject: [PATCH 06/93] NOTICK: Replace global dependency exclusions with dependency substitution. (#7099) --- build.gradle | 56 ++++++++++++++++++++++++++++++------------------- settings.gradle | 1 - 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/build.gradle b/build.gradle index 82d6eeef96..ae3e8f196e 100644 --- a/build.gradle +++ b/build.gradle @@ -421,43 +421,55 @@ allprojects { configurations { all { resolutionStrategy { - // Force dependencies to use the same version of Kotlin as Corda. - force "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - force "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - force "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - - // Force dependencies to use the same version of Guava as Corda. - force "com.google.guava:guava:$guava_version" - // Demand that everything uses our given version of Netty. eachDependency { details -> if (details.requested.group == 'io.netty' && details.requested.name.startsWith('netty-')) { - if (details.requested.name.startsWith('netty-tcnative')){ + if (details.requested.name.startsWith('netty-tcnative')) { details.useVersion tcnative_version } else { details.useVersion netty_version } } } + + dependencySubstitution { + // We want to use SLF4J's version of these bindings: jcl-over-slf4j + // Remove any transitive dependency on Apache's version. + substitute module('commons-logging:commons-logging') with module("org.slf4j:jcl-over-slf4j:$slf4j_version") + + // Remove any transitive dependency on Logback (e.g. Liquibase 3.6 introduces this dependency) + substitute module('ch.qos.logback:logback-classic') with module("org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version") + + // Netty-All is an uber-jar which contains every Netty module. + // Exclude it to force us to use the individual Netty modules instead. + substitute module('io.netty:netty-all') with module("io.netty:netty-common:$netty_version") + + // Force dependencies to use the same version of Guava as Corda. + substitute module('com.google.guava:guava') with module("com.google.guava:guava:$guava_version") + + // Effectively delete this unused and unwanted transitive dependency of Artemis. + substitute module('org.jgroups:jgroups') with module("org.apache.activemq:artemis-commons:$artemis_version") + } } } - compile { - // We want to use SLF4J's version of these bindings: jcl-over-slf4j - // Remove any transitive dependency on Apache's version. - exclude group: 'commons-logging', module: 'commons-logging' - // Remove any transitive dependency on Logback (e.g. Liquibase 3.6 introduces this dependency) - exclude group: 'ch.qos.logback' - // 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' - } - runtime { - // We never want isolated.jar on classPath, since we want to test jar being dynamically loaded as an attachment - exclude module: 'isolated' + // Select all of the compileClasspath and runtimeClasspath etc configurations, + // but NOT the "classpath" configuration, as that is used by the Gradle plugins. + matching { it.name.endsWith("Classpath") }.configureEach { cfg -> + cfg.resolutionStrategy { + dependencySubstitution { + // Force dependencies to use the same version of Kotlin as Corda. + substitute module('org.jetbrains.kotlin:kotlin-stdlib-jdk8') with module("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version") + substitute module('org.jetbrains.kotlin:kotlin-stdlib-jdk7') with module("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version") + substitute module('org.jetbrains.kotlin:kotlin-stdlib-common') with module("org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version") + substitute module('org.jetbrains.kotlin:kotlin-stdlib') with module("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version") + substitute module('org.jetbrains.kotlin:kotlin-reflect') with module("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version") + } + } } } } + sonarqube { properties { property "sonar.projectName", "Corda" diff --git a/settings.gradle b/settings.gradle index 97dfbdd783..18cc562f45 100644 --- a/settings.gradle +++ b/settings.gradle @@ -31,7 +31,6 @@ rootProject.name = 'corda-project' include 'confidential-identities' include 'finance:contracts' include 'finance:workflows' -include 'isolated' include 'core' include 'core-tests' include 'docs' From 787d0cde99eb9bb9cbc393a842212653ff9eb515 Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Thu, 10 Mar 2022 15:38:41 +0000 Subject: [PATCH 07/93] INFRA-1728 set correct java version for JDK 11 base image (#7102) Use Specific JDK version not the latest Java 11 base image --- .ci/dev/compatibility/DockerfileJDK11 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/dev/compatibility/DockerfileJDK11 b/.ci/dev/compatibility/DockerfileJDK11 index 263c42a391..23aa144955 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 \ @@ -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 4ca2927dd3dea7224d75fa8f8e8c42480be121d2 Mon Sep 17 00:00:00 2001 From: Connel McGovern <100574906+mcgovc@users.noreply.github.com> Date: Tue, 15 Mar 2022 07:57:04 +0000 Subject: [PATCH 08/93] INFRA-1735 Teams notification's for C4 (#7105) * INFRA-1728 set correct java version for JDK 11 base image --- .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 82d0f66399..c9675d84f7 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: Wed, 23 Mar 2022 12:23:11 +0000 Subject: [PATCH 09/93] INFRA-1743 Activate C4 email notifications Open source and Ent --- .ci/dev/regression/Jenkinsfile | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 82d0f66399..b28f1c0448 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -7,6 +7,7 @@ /** * Sense environment */ +boolean isReleaseBranch = (env.BRANCH_NAME =~ /^release\/.*/) boolean isReleaseTag = (env.TAG_NAME =~ /^release-.*(? Date: Wed, 23 Mar 2022 13:09:00 +0000 Subject: [PATCH 10/93] INFRA-1743 Activate C4 email notifications Open source and Ent --- .ci/dev/regression/Jenkinsfile | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index f24486bb24..8c554e3e66 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -7,7 +7,6 @@ /** * Sense environment */ - boolean isReleaseBranch = (env.BRANCH_NAME =~ /^release\/os\/.*/) boolean isReleaseTag = (env.TAG_NAME =~ /^release-.*(? Date: Mon, 4 Apr 2022 09:48:18 +0100 Subject: [PATCH 11/93] NOTICK: Force Gradle to use the most recent SNAPSHOTs. --- build.gradle | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3498bcdd30..7bd87e42aa 100644 --- a/build.gradle +++ b/build.gradle @@ -206,7 +206,8 @@ buildscript { classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8" } - configurations.all { + configurations.classpath { + // FORCE Gradle to use latest SNAPSHOT plugins. resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } } @@ -472,6 +473,9 @@ allprojects { substitute module('org.jetbrains.kotlin:kotlin-stdlib') with module("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version") substitute module('org.jetbrains.kotlin:kotlin-reflect') with module("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version") } + + // FORCE Gradle to use latest SNAPSHOT dependencies. + cacheChangingModulesFor 0, 'seconds' } } } From 1262379447f888cbebea19837ad65891f25eb0ec Mon Sep 17 00:00:00 2001 From: Adel El-Beik Date: Sat, 2 Apr 2022 18:00:14 +0100 Subject: [PATCH 12/93] ENT-6607: Update hibernate to 5.4.32.Final --- constants.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constants.properties b/constants.properties index 0aedd166b9..6457f40680 100644 --- a/constants.properties +++ b/constants.properties @@ -72,7 +72,7 @@ mockitoKotlinVersion=1.6.0 hamkrestVersion=1.7.0.0 joptSimpleVersion=5.0.2 jansiVersion=1.18 -hibernateVersion=5.4.3.Final +hibernateVersion=5.4.32.Final # h2Version - Update docs if renamed or removed. h2Version=1.4.199 rxjavaVersion=1.3.8 From 05be5d6c42c16a453ebf0b338322be37fa536ccd Mon Sep 17 00:00:00 2001 From: Viktor Kolomeyko Date: Mon, 25 Apr 2022 09:53:06 +0100 Subject: [PATCH 13/93] ENT-6627: Update version of Shiro to 1.8.0 (#7153) --- constants.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constants.properties b/constants.properties index 6457f40680..94737aacd9 100644 --- a/constants.properties +++ b/constants.properties @@ -81,7 +81,7 @@ eddsaVersion=0.3.0 dependencyCheckerVersion=5.2.0 commonsCollectionsVersion=4.3 beanutilsVersion=1.9.4 -shiroVersion=1.4.1 +shiroVersion=1.8.0 hikariVersion=3.3.1 liquibaseVersion=3.6.3 dockerComposeRuleVersion=1.5.0 From 9bda96ff0a9d5a8318a3e1a8b1300b95396fa05a Mon Sep 17 00:00:00 2001 From: ronanbrowne88 Date: Sun, 1 May 2022 11:27:44 +0100 Subject: [PATCH 14/93] INFRA-1746 add slack notifications --- .ci/dev/regression/Jenkinsfile | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index b41c57aaff..249844847b 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -421,6 +421,21 @@ pipeline { } } } + success { + script { + sendSlackNotifications("good", "BUILD PASSED", false, "#corda-corda4-build-notifications") + } + } + unstable { + script { + sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", false, "#corda-corda4-build-notifications") + } + } + failure { + script { + sendSlackNotifications("danger", "BUILD FAILURE", true, "#corda-corda4-build-notifications") + } + } cleanup { deleteDir() /* clean up our workspace */ } From 5d28856dc067c2bb29bcf063a558d59e09d27ad7 Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Sun, 1 May 2022 11:32:33 +0100 Subject: [PATCH 15/93] NOTICK: fix build issue post merge and remove some redundant code post slack migration noticed 4.10 release branch CI is broken due to duplicate entries in options block , I've removed both of these plus accompanying logic as there is no need for MSTeams notifications goign forward --- .ci/dev/regression/Jenkinsfile | 35 ---------------------------------- 1 file changed, 35 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index b41c57aaff..7c60ea66d7 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -41,17 +41,6 @@ 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 - */ -def teamsWebHookURL = "" -if (isReleaseBranch || isReleaseTag){ - withCredentials([string(credentialsId: 'ms-teams-webhook', variable: 'webhook_url')]) { - teamsWebHookURL = "$webhook_url" - } -} - /** * Common Gradle arguments for all Gradle executions */ @@ -72,33 +61,9 @@ pipeline { */ options { 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}" - ]]) parallelsAlwaysFailFast() timeout(time: 6, unit: 'HOURS') timestamps() - 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 { From 7ce0ab2789a8ea5ee949ba02c2511abdb4dcd173 Mon Sep 17 00:00:00 2001 From: ronanbrowne88 Date: Sun, 1 May 2022 11:35:50 +0100 Subject: [PATCH 16/93] INFRA-1746 tidy up --- .ci/dev/regression/Jenkinsfile | 35 ---------------------------------- 1 file changed, 35 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 249844847b..06aa479a0e 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -41,17 +41,6 @@ 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 - */ -def teamsWebHookURL = "" -if (isReleaseBranch || isReleaseTag){ - withCredentials([string(credentialsId: 'ms-teams-webhook', variable: 'webhook_url')]) { - teamsWebHookURL = "$webhook_url" - } -} - /** * Common Gradle arguments for all Gradle executions */ @@ -72,33 +61,9 @@ pipeline { */ options { 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}" - ]]) parallelsAlwaysFailFast() timeout(time: 6, unit: 'HOURS') timestamps() - 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 { From 444a1b8fd502100dde91eee200bc83f106e6747a Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Mon, 2 May 2022 11:40:59 +0100 Subject: [PATCH 17/93] NOTICK: add shared library call --- .ci/dev/regression/Jenkinsfile | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 06aa479a0e..ffdddd0c00 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -3,6 +3,7 @@ * Jenkins pipeline to build Corda OS release branches and tags. * PLEASE NOTE: we DO want to run a build for each commit!!! */ +@Library('corda-shared-build-pipeline-steps') /** * Sense environment From 7ac38891720c9a5a7ec859779d43da97d2338473 Mon Sep 17 00:00:00 2001 From: Connel McGovern <100574906+mcgovc@users.noreply.github.com> Date: Mon, 9 May 2022 13:22:40 +0100 Subject: [PATCH 18/93] INFRA-1743 E-mail & Slack notifications --- .ci/dev/regression/Jenkinsfile | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 8c554e3e66..b0dd425fff 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -408,19 +408,21 @@ pipeline { } } } + success { + script { + sendSlackNotifications("good", "BUILD PASSED", false, "#corda-corda4-open-source-build-notifications") + } + } + unstable { + script { + sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", false, "#corda-corda4-open-source-build-notifications") + } + } failure { script { - def statusSymbol = '\u274c' + sendSlackNotifications("danger", "BUILD FAILURE", true, "#corda-corda4-open-source-build-notifications") if (isReleaseTag || isReleaseBranch || isReleaseCandidate) { - emailext subject: "$statusSymbol " + '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!', - body: '${SCRIPT, template="groovy-html.template"}', - recipientProviders: [ - [$class: 'CulpritsRecipientProvider'], - [$class: 'RequesterRecipientProvider'] - ], - mimeType: 'text/html', - replyTo: '$DEFAULT_REPLYTO', - to: "adel.el-beik@r3.com" + sendEmailNotifications("${env.EMAIL_RECIPIENTS}") } } } From fa634fd158c3e30e41cbc62b3e72d238fc697277 Mon Sep 17 00:00:00 2001 From: Connel McGovern <100574906+mcgovc@users.noreply.github.com> Date: Mon, 9 May 2022 13:30:25 +0100 Subject: [PATCH 19/93] Update Jenkinsfile --- .ci/dev/regression/Jenkinsfile | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index b0dd425fff..c81aa610e3 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -3,6 +3,7 @@ * Jenkins pipeline to build Corda OS release branches and tags. * PLEASE NOTE: we DO want to run a build for each commit!!! */ +@Library('corda-shared-build-pipeline-steps') /** * Sense environment @@ -41,17 +42,6 @@ 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 - */ -def teamsWebHookURL = "" -if (isReleaseBranch || isReleaseTag){ - withCredentials([string(credentialsId: 'ms-teams-webhook', variable: 'webhook_url')]) { - teamsWebHookURL = "$webhook_url" - } -} - /** * Common Gradle arguments for all Gradle executions */ @@ -71,18 +61,6 @@ pipeline { */ options { 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}" - ]]) parallelsAlwaysFailFast() timeout(time: 6, unit: 'HOURS') timestamps() @@ -103,6 +81,7 @@ pipeline { CORDA_ARTIFACTORY_USERNAME = "${env.ARTIFACTORY_CREDENTIALS_USR}" CORDA_BUILD_EDITION = "${buildEdition}" DOCKER_URL = "https://index.docker.io/v1/" + EMAIL_RECIPIENTS = credentials('corda4-email-recipient') } stages { From 652d5c1551ea0dd8683324403953688eb5c7b2af Mon Sep 17 00:00:00 2001 From: Connel McGovern <100574906+mcgovc@users.noreply.github.com> Date: Mon, 9 May 2022 16:15:22 +0100 Subject: [PATCH 20/93] Update Jenkinsfile --- .ci/dev/regression/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 44edc26bf9..42bed4f217 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -390,13 +390,13 @@ pipeline { } success { script { - sendSlackNotifications("good", "BUILD PASSED", false, "#corda-corda4-open-source-build-notifications") + sendSlackNotifications("good", "BUILD PASSED", true, "#corda-corda4-open-source-build-notifications") } } unstable { script { - sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", false, "#corda-corda4-open-source-build-notifications") + sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", true, "#corda-corda4-open-source-build-notifications") } } failure { From 8a2f4431df940ae4639d24ff8a86d1a9b554b64d Mon Sep 17 00:00:00 2001 From: Connel McGovern <100574906+mcgovc@users.noreply.github.com> Date: Wed, 11 May 2022 14:14:09 +0100 Subject: [PATCH 21/93] NOTICK Remove Slack tagging on successful/unstable builds --- .ci/dev/regression/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 42bed4f217..44edc26bf9 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -390,13 +390,13 @@ pipeline { } success { script { - sendSlackNotifications("good", "BUILD PASSED", true, "#corda-corda4-open-source-build-notifications") + sendSlackNotifications("good", "BUILD PASSED", false, "#corda-corda4-open-source-build-notifications") } } unstable { script { - sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", true, "#corda-corda4-open-source-build-notifications") + sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", false, "#corda-corda4-open-source-build-notifications") } } failure { From 12f339a3434c672daa387ce163b749ad53bd7286 Mon Sep 17 00:00:00 2001 From: Dimos Raptis Date: Wed, 18 May 2022 16:55:06 +0100 Subject: [PATCH 22/93] Port netty upgrade to constants.properties --- constants.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constants.properties b/constants.properties index 0e67ddd2c3..54579216f7 100644 --- a/constants.properties +++ b/constants.properties @@ -55,7 +55,7 @@ assertjVersion=3.12.2 slf4JVersion=1.7.30 log4JVersion=2.17.1 okhttpVersion=3.14.2 -nettyVersion=4.1.68.Final +nettyVersion=4.1.76.Final fileuploadVersion=1.4 kryoVersion=4.0.2 kryoSerializerVersion=0.43 From 853c95b880d08b496cc8e38ce94116d3a67b395e Mon Sep 17 00:00:00 2001 From: Katelyn Baker Date: Mon, 23 May 2022 15:32:06 +0100 Subject: [PATCH 23/93] NOTICK - Cross link Arch V1 to the Arch V2 repo (#7178) Co-authored-by: Ben Pester <61828828+benpesterr3@users.noreply.github.com> --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index a84c2d5957..0c22243385 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ Corda is an open source blockchain project, designed for business from the start. Only Corda allows you to build interoperable blockchain networks that transact in strict privacy. Corda's smart contract technology allows businesses to transact directly, with value. +## Architecure Evolution + +The code present in this repository reflects the first version of the implementation of the Corda model for DLT technology. This first architecture version covers Corda versions 1 through 4 and continues to deliver on the promise of DLT for both the open source community and industry as a whole. + +However, like all things, Corda must evolve to serve the more stringent needs of today. This is why the second (and current) version of the Corda Arcchitecture can be found [here](https://github.com/corda/corda-runtime-os) and will form the basis of the Corda 5 release. + ## Features * Smart contracts that can be written in Java and other JVM languages From c7eab9980b18152298dbb6c4a785400646259d2c Mon Sep 17 00:00:00 2001 From: Viktor Kolomeyko Date: Thu, 26 May 2022 09:35:27 +0100 Subject: [PATCH 24/93] NOTICK: Update Docker ReadMe.md (#7176) --- docker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/README.md b/docker/README.md index 88a012b029..6b47896ac2 100644 --- a/docker/README.md +++ b/docker/README.md @@ -26,7 +26,7 @@ results in If no image variant is specified, all available image variants will be built. The default repository for all images is `corda/corda` and you will need official R3 credentials -for Artifactory to push there. [Ross Nicoll](ross.nicoll@r3.com) (or other Artifactory administrators) can assist with this if needed, +for Artifactory to push there. R3's Artifactory administrators can assist with this if needed, otherwise you can override the repository name using the `docker.image.repository` Gradle property. e.g. From 206f3ac0882dba6fa7cc8cd14cc130a0793a1c37 Mon Sep 17 00:00:00 2001 From: Waldemar Zurowski Date: Fri, 27 May 2022 09:22:29 +0200 Subject: [PATCH 25/93] Added missing update of Jackson version --- constants.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constants.properties b/constants.properties index 408d607765..87362e8311 100644 --- a/constants.properties +++ b/constants.properties @@ -46,7 +46,7 @@ capsuleVersion=1.0.3 asmVersion=7.1 artemisVersion=2.19.1 # TODO Upgrade Jackson only when corda is using kotlin 1.3.10 -jacksonVersion=2.13.1 +jacksonVersion=2.13.3 jacksonKotlinVersion=2.9.7 jettyVersion=9.4.19.v20190610 jerseyVersion=2.25 From 043c4e5dccac7f43f7e775ac1ee0b87aeb292ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Waldemar=20=C5=BBurowski?= <45210402+wzur-r3@users.noreply.github.com> Date: Mon, 30 May 2022 10:57:04 +0200 Subject: [PATCH 26/93] NOTICK: remove obsolete parameter (#7193) * removed `project` parameter from `jira-sync-closed-action` as it was never used --- .github/workflows/jira_close_issue.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/jira_close_issue.yml b/.github/workflows/jira_close_issue.yml index 1af7f841e5..dfe3d2443a 100644 --- a/.github/workflows/jira_close_issue.yml +++ b/.github/workflows/jira_close_issue.yml @@ -11,7 +11,6 @@ jobs: - name: Close uses: corda/jira-sync-closed-action@master with: - project: CORDA jiraBaseUrl: https://r3-cev.atlassian.net jiraEmail: ${{ secrets.JIRA_USER_EMAIL }} jiraToken: ${{ secrets.JIRA_API_TOKEN }} From b76fc7de598d84af2e60c64f62a7c32bb0e2a945 Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Tue, 7 Jun 2022 16:20:05 +0100 Subject: [PATCH 27/93] Introduced node status; published via JMX --- .../net/corda/node/internal/AbstractNode.kt | 24 ++++++++++++++++++- .../kotlin/net/corda/node/internal/Node.kt | 4 +--- 2 files changed, 24 insertions(+), 4 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 3d83201494..e611488cd7 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -1,6 +1,7 @@ package net.corda.node.internal import co.paralleluniverse.fibers.instrument.Retransform +import com.codahale.metrics.Gauge import com.codahale.metrics.MetricRegistry import com.google.common.collect.MutableClassToInstanceMap import com.google.common.util.concurrent.MoreExecutors @@ -383,6 +384,15 @@ abstract class AbstractNode(val configuration: NodeConfiguration, protected val keyStoreHandler = KeyStoreHandler(configuration, cryptoService) + enum class NodeStatus { + WAITING_TO_START, + STARTING, + STARTED, + STOPPING + } + + private var nodeStatus = NodeStatus.WAITING_TO_START + private fun T.tokenize(): T { tokenizableServices?.add(this as? SerializeAsToken ?: throw IllegalStateException("${this::class.java} is expected to be extending from SerializeAsToken")) @@ -524,6 +534,12 @@ abstract class AbstractNode(val configuration: NodeConfiguration, Node.printBasicNodeInfo("CorDapp schemas synchronised") } + private fun setNodeStatus(st : NodeStatus) { + log.info("Node status update: [$nodeStatus] -> [$st]") + nodeStatus = st + } + + @Suppress("ComplexMethod") open fun start(): S { check(started == null) { "Node has already been started" } @@ -533,9 +549,12 @@ abstract class AbstractNode(val configuration: NodeConfiguration, } nodeLifecycleEventsDistributor.distributeEvent(NodeLifecycleEvent.BeforeNodeStart(nodeServicesContext)) log.info("Node starting up ...") + setNodeStatus(NodeStatus.STARTING) + + initialiseJolokia() + monitoringService.metrics.register(MetricRegistry.name("Node", "Status"), Gauge { nodeStatus }) val trustRoots = initKeyStores() - initialiseJolokia() schemaService.mappedSchemasWarnings().forEach { val warning = it.toWarning() @@ -658,6 +677,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, log.warn("Not distributing events as NetworkMap is not ready") } } + setNodeStatus(NodeStatus.STARTED) return resultingNodeInfo } @@ -1050,6 +1070,8 @@ abstract class AbstractNode(val configuration: NodeConfiguration, open fun stop() { + setNodeStatus(NodeStatus.STOPPING) + nodeLifecycleEventsDistributor.distributeEvent(NodeLifecycleEvent.StateMachineStopped(nodeServicesContext)) nodeLifecycleEventsDistributor.distributeEvent(NodeLifecycleEvent.BeforeNodeStop(nodeServicesContext)) diff --git a/node/src/main/kotlin/net/corda/node/internal/Node.kt b/node/src/main/kotlin/net/corda/node/internal/Node.kt index 87f27d7415..1747740035 100644 --- a/node/src/main/kotlin/net/corda/node/internal/Node.kt +++ b/node/src/main/kotlin/net/corda/node/internal/Node.kt @@ -580,14 +580,12 @@ open class Node(configuration: NodeConfiguration, } override fun start(): NodeInfo { + registerJmxReporter(services.monitoringService.metrics) registerDefaultExceptionHandler() initialiseSerialization() val nodeInfo: NodeInfo = super.start() nodeReadyFuture.thenMatch({ serverThread.execute { - - registerJmxReporter(services.monitoringService.metrics) - _startupComplete.set(Unit) } }, From 500be9cbcd682aec6b5f89eed9a4d62b22c6568d Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Wed, 8 Jun 2022 13:36:50 +0100 Subject: [PATCH 28/93] Post-review updates; added integration tests --- .../net/corda/nodeapi/internal/NodeStatus.kt | 8 ++++ .../kotlin/net/corda/node/jmx/NodeStatus.kt | 45 +++++++++++++++++++ .../kotlin/net/corda/node/jmx/Publish.kt | 29 ++++++++++++ .../net/corda/node/internal/AbstractNode.kt | 9 +--- 4 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 node-api/src/main/kotlin/net/corda/nodeapi/internal/NodeStatus.kt create mode 100644 node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt create mode 100644 node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/NodeStatus.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/NodeStatus.kt new file mode 100644 index 0000000000..c6cf35f053 --- /dev/null +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/NodeStatus.kt @@ -0,0 +1,8 @@ +package net.corda.nodeapi.internal + +enum class NodeStatus { + WAITING_TO_START, + STARTING, + STARTED, + STOPPING +} diff --git a/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt b/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt new file mode 100644 index 0000000000..01aee4ee68 --- /dev/null +++ b/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt @@ -0,0 +1,45 @@ +package net.corda.node.jmx + +import com.fasterxml.jackson.databind.ObjectMapper +import net.corda.nodeapi.internal.NodeStatus +import net.corda.testing.driver.DriverParameters +import net.corda.testing.driver.JmxPolicy +import net.corda.testing.driver.driver +import org.junit.Test +import java.net.HttpURLConnection +import java.net.HttpURLConnection.* +import java.net.URL +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class NodeStatus { + + @Test(timeout=300_000) + fun `node status is published via JMX`() { + driver(DriverParameters(notarySpecs = emptyList(), jmxPolicy = JmxPolicy.defaultEnabled())) { + val jmxAddress = startNode().get().jmxAddress.toString() + val nodeStatusURL = URL("http://$jmxAddress/jolokia/read/net.corda:name=Status,type=Node") + var jmxInfo = "" + + with(nodeStatusURL.openConnection() as HttpURLConnection) { + requestMethod = "GET" + inputStream.bufferedReader().use { + it.lines().forEach { line -> + jmxInfo += line + } + } + } + + assertTrue { + jmxInfo.isNotEmpty() + } + + val jsonTree = ObjectMapper().readTree(jmxInfo) + val httpStatus = jsonTree.get("status").asInt() + val nodeStatus = jsonTree.get("value").get("Value").asText() + + assertEquals(httpStatus, HTTP_OK) + assertEquals(nodeStatus, NodeStatus.STARTED.toString()) + } + } +} \ No newline at end of file diff --git a/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt b/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt new file mode 100644 index 0000000000..07496e7bc1 --- /dev/null +++ b/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt @@ -0,0 +1,29 @@ +package net.corda.node.jmx + +import net.corda.testing.driver.DriverParameters +import net.corda.testing.driver.JmxPolicy +import net.corda.testing.driver.driver +import org.junit.Test +import java.net.HttpURLConnection +import java.net.URL +import kotlin.test.assertTrue + +class Publish { + + @Test(timeout=300_000) + fun `node publishes node information via JMX when configured to do so`() { + driver(DriverParameters(notarySpecs = emptyList(), jmxPolicy = JmxPolicy.defaultEnabled())) { + val jmxAddress = startNode().get().jmxAddress.toString() + val nodeStatusURL = URL("http://$jmxAddress/jolokia/read/net.corda:*") + var httpResponse = HttpURLConnection.HTTP_NOT_FOUND + with(nodeStatusURL.openConnection() as HttpURLConnection) { + requestMethod = "GET" + httpResponse = responseCode + } + + assertTrue { + httpResponse == HttpURLConnection.HTTP_OK + } + } + } +} \ 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 e611488cd7..705d5dc447 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -147,6 +147,7 @@ import net.corda.node.utilities.BindableNamedCacheFactory import net.corda.node.utilities.NamedThreadFactory import net.corda.node.utilities.NotaryLoader import net.corda.nodeapi.internal.NodeInfoAndSigned +import net.corda.nodeapi.internal.NodeStatus import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.cordapp.CordappLoader import net.corda.nodeapi.internal.cryptoservice.CryptoService @@ -384,13 +385,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, protected val keyStoreHandler = KeyStoreHandler(configuration, cryptoService) - enum class NodeStatus { - WAITING_TO_START, - STARTING, - STARTED, - STOPPING - } - + @Volatile private var nodeStatus = NodeStatus.WAITING_TO_START private fun T.tokenize(): T { From 518befabeb329084b7268aa685f098b0e8dbb3a1 Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Wed, 8 Jun 2022 13:54:16 +0100 Subject: [PATCH 29/93] Resolved detekt error --- .../integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt b/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt index 01aee4ee68..7f68b9584f 100644 --- a/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt +++ b/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt @@ -7,13 +7,13 @@ import net.corda.testing.driver.JmxPolicy import net.corda.testing.driver.driver import org.junit.Test import java.net.HttpURLConnection -import java.net.HttpURLConnection.* +import java.net.HttpURLConnection.HTTP_OK import java.net.URL import kotlin.test.assertEquals import kotlin.test.assertTrue class NodeStatus { - + @Test(timeout=300_000) fun `node status is published via JMX`() { driver(DriverParameters(notarySpecs = emptyList(), jmxPolicy = JmxPolicy.defaultEnabled())) { From fce95dd276519f794ee64c58053667b4761b30dc Mon Sep 17 00:00:00 2001 From: Chris Cochrane <78791827+chriscochrane@users.noreply.github.com> Date: Wed, 8 Jun 2022 15:50:34 +0100 Subject: [PATCH 30/93] Update node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt Co-authored-by: Viktor Kolomeyko --- .../integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt b/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt index 7f68b9584f..24116f6fe1 100644 --- a/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt +++ b/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt @@ -12,7 +12,7 @@ import java.net.URL import kotlin.test.assertEquals import kotlin.test.assertTrue -class NodeStatus { +class NodeStatusTest { @Test(timeout=300_000) fun `node status is published via JMX`() { From 3c0c1a01a2c9ebf02f08e7c947055b7f10876d8a Mon Sep 17 00:00:00 2001 From: Chris Cochrane <78791827+chriscochrane@users.noreply.github.com> Date: Wed, 8 Jun 2022 15:50:48 +0100 Subject: [PATCH 31/93] Update node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt Co-authored-by: Viktor Kolomeyko --- node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt b/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt index 07496e7bc1..0961d31d67 100644 --- a/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt +++ b/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt @@ -8,7 +8,7 @@ import java.net.HttpURLConnection import java.net.URL import kotlin.test.assertTrue -class Publish { +class PublishTest { @Test(timeout=300_000) fun `node publishes node information via JMX when configured to do so`() { From 02321465159799e98158d09f7833507347083d97 Mon Sep 17 00:00:00 2001 From: Chris Cochrane <78791827+chriscochrane@users.noreply.github.com> Date: Wed, 8 Jun 2022 16:01:25 +0100 Subject: [PATCH 32/93] Update node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt Co-authored-by: Viktor Kolomeyko --- .../integration-test/kotlin/net/corda/node/jmx/Publish.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt b/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt index 0961d31d67..cf899e2ea7 100644 --- a/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt +++ b/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt @@ -15,7 +15,10 @@ class PublishTest { driver(DriverParameters(notarySpecs = emptyList(), jmxPolicy = JmxPolicy.defaultEnabled())) { val jmxAddress = startNode().get().jmxAddress.toString() val nodeStatusURL = URL("http://$jmxAddress/jolokia/read/net.corda:*") - var httpResponse = HttpURLConnection.HTTP_NOT_FOUND + val httpResponse = with(nodeStatusURL.openConnection() as HttpURLConnection) { + requestMethod = "GET" + responseCode + } with(nodeStatusURL.openConnection() as HttpURLConnection) { requestMethod = "GET" httpResponse = responseCode From 4b1aabb164b3987b7aff2ed12de38b128e62995a Mon Sep 17 00:00:00 2001 From: Chris Cochrane <78791827+chriscochrane@users.noreply.github.com> Date: Wed, 8 Jun 2022 16:01:43 +0100 Subject: [PATCH 33/93] Update node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt Co-authored-by: Viktor Kolomeyko --- .../kotlin/net/corda/node/jmx/NodeStatus.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt b/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt index 24116f6fe1..c889c1e14d 100644 --- a/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt +++ b/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt @@ -19,7 +19,12 @@ class NodeStatusTest { driver(DriverParameters(notarySpecs = emptyList(), jmxPolicy = JmxPolicy.defaultEnabled())) { val jmxAddress = startNode().get().jmxAddress.toString() val nodeStatusURL = URL("http://$jmxAddress/jolokia/read/net.corda:name=Status,type=Node") - var jmxInfo = "" + val jmxInfo = with(nodeStatusURL.openConnection() as HttpURLConnection) { + requestMethod = "GET" + inputStream.bufferedReader().use { + it.lines().collect(Collectors.toList()).joinToString() + } + } with(nodeStatusURL.openConnection() as HttpURLConnection) { requestMethod = "GET" From f0d530ab8bab069f0effa762c490421a4d67f802 Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Wed, 8 Jun 2022 16:30:06 +0100 Subject: [PATCH 34/93] Post review updates; renamed tests/files, neater Kotlin test code --- .../node/jmx/{NodeStatus.kt => NodeStatusTest.kt} | 12 ++---------- .../corda/node/jmx/{Publish.kt => PublishTest.kt} | 6 +----- 2 files changed, 3 insertions(+), 15 deletions(-) rename node/src/integration-test/kotlin/net/corda/node/jmx/{NodeStatus.kt => NodeStatusTest.kt} (77%) rename node/src/integration-test/kotlin/net/corda/node/jmx/{Publish.kt => PublishTest.kt} (75%) diff --git a/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt b/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatusTest.kt similarity index 77% rename from node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt rename to node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatusTest.kt index c889c1e14d..6e3850bffc 100644 --- a/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatus.kt +++ b/node/src/integration-test/kotlin/net/corda/node/jmx/NodeStatusTest.kt @@ -9,6 +9,7 @@ import org.junit.Test import java.net.HttpURLConnection import java.net.HttpURLConnection.HTTP_OK import java.net.URL +import java.util.stream.Collectors import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -19,22 +20,13 @@ class NodeStatusTest { driver(DriverParameters(notarySpecs = emptyList(), jmxPolicy = JmxPolicy.defaultEnabled())) { val jmxAddress = startNode().get().jmxAddress.toString() val nodeStatusURL = URL("http://$jmxAddress/jolokia/read/net.corda:name=Status,type=Node") - val jmxInfo = with(nodeStatusURL.openConnection() as HttpURLConnection) { + val jmxInfo = with(nodeStatusURL.openConnection() as HttpURLConnection) { requestMethod = "GET" inputStream.bufferedReader().use { it.lines().collect(Collectors.toList()).joinToString() } } - with(nodeStatusURL.openConnection() as HttpURLConnection) { - requestMethod = "GET" - inputStream.bufferedReader().use { - it.lines().forEach { line -> - jmxInfo += line - } - } - } - assertTrue { jmxInfo.isNotEmpty() } diff --git a/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt b/node/src/integration-test/kotlin/net/corda/node/jmx/PublishTest.kt similarity index 75% rename from node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt rename to node/src/integration-test/kotlin/net/corda/node/jmx/PublishTest.kt index cf899e2ea7..f51e08a2c0 100644 --- a/node/src/integration-test/kotlin/net/corda/node/jmx/Publish.kt +++ b/node/src/integration-test/kotlin/net/corda/node/jmx/PublishTest.kt @@ -15,14 +15,10 @@ class PublishTest { driver(DriverParameters(notarySpecs = emptyList(), jmxPolicy = JmxPolicy.defaultEnabled())) { val jmxAddress = startNode().get().jmxAddress.toString() val nodeStatusURL = URL("http://$jmxAddress/jolokia/read/net.corda:*") - val httpResponse = with(nodeStatusURL.openConnection() as HttpURLConnection) { + val httpResponse = with(nodeStatusURL.openConnection() as HttpURLConnection) { requestMethod = "GET" responseCode } - with(nodeStatusURL.openConnection() as HttpURLConnection) { - requestMethod = "GET" - httpResponse = responseCode - } assertTrue { httpResponse == HttpURLConnection.HTTP_OK From 03fa529292b80c996f44c83c8b3caedbe06c2480 Mon Sep 17 00:00:00 2001 From: Chris Cochrane <78791827+chriscochrane@users.noreply.github.com> Date: Fri, 10 Jun 2022 19:56:02 +0100 Subject: [PATCH 35/93] ENT-6791 New service lifecycle event published just before starting the state machine (#7164) --- .../node/services/ServiceLifecycleObserver.kt | 1 + .../lifecycle/NodeLifecycleObserver.kt | 1 + .../corda/node/flows/FlowEntityManagerTest.kt | 33 +++--- .../CordaServiceLifecycleFatalTests.kt | 12 +- .../services/CordaServiceLifecycleTests.kt | 109 ++++++++++++++++-- .../net/corda/node/internal/AbstractNode.kt | 5 + .../corda/node/internal/AppServiceHubImpl.kt | 4 + 7 files changed, 136 insertions(+), 29 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/node/services/ServiceLifecycleObserver.kt b/core/src/main/kotlin/net/corda/core/node/services/ServiceLifecycleObserver.kt index 9921894f80..ea4302ab22 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/ServiceLifecycleObserver.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/ServiceLifecycleObserver.kt @@ -25,6 +25,7 @@ enum class ServiceLifecycleEvent { * sense for Corda node to continue its operation. The lifecycle events dispatcher will endeavor to terminate node's JVM as soon * as practically possible. */ + BEFORE_STATE_MACHINE_START, STATE_MACHINE_STARTED, } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/lifecycle/NodeLifecycleObserver.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/lifecycle/NodeLifecycleObserver.kt index 0232029188..b960f8bdb0 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/lifecycle/NodeLifecycleObserver.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/lifecycle/NodeLifecycleObserver.kt @@ -49,6 +49,7 @@ interface NodeLifecycleObserver { sealed class NodeLifecycleEvent(val reversedPriority: Boolean = false) { class BeforeNodeStart(val nodeInitialContext: NodeInitialContext) : NodeLifecycleEvent() class AfterNodeStart(val nodeServicesContext: T) : NodeLifecycleEvent() + class BeforeStateMachineStart(val nodeServicesContext: T) : NodeLifecycleEvent() class StateMachineStarted(val nodeServicesContext: T) : NodeLifecycleEvent() class StateMachineStopped(val nodeServicesContext: T) : NodeLifecycleEvent(reversedPriority = true) class BeforeNodeStop(val nodeServicesContext: T) : NodeLifecycleEvent(reversedPriority = true) diff --git a/node/src/integration-test/kotlin/net/corda/node/flows/FlowEntityManagerTest.kt b/node/src/integration-test/kotlin/net/corda/node/flows/FlowEntityManagerTest.kt index fac7f780c5..b54d9d0d75 100644 --- a/node/src/integration-test/kotlin/net/corda/node/flows/FlowEntityManagerTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/flows/FlowEntityManagerTest.kt @@ -16,6 +16,7 @@ import net.corda.core.internal.concurrent.transpose import net.corda.core.messaging.startFlow import net.corda.core.node.AppServiceHub import net.corda.core.node.services.CordaService +import net.corda.core.node.services.ServiceLifecycleEvent import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder @@ -854,19 +855,25 @@ class FlowEntityManagerTest : AbstractFlowEntityManagerTest() { init { if (includeRawUpdates) { services.register { - services.vaultService.rawUpdates.subscribe { - if (insertionType == InsertionType.ENTITY_MANAGER) { - services.withEntityManager { - persist(entityWithIdOne) - persist(entityWithIdTwo) - persist(entityWithIdThree) - } - } else { - services.jdbcSession().run { - insert(entityWithIdOne) - insert(entityWithIdTwo) - insert(entityWithIdThree) - } + processEvent(it) + } + } + } + + private fun processEvent(event : ServiceLifecycleEvent) { + if (event == ServiceLifecycleEvent.STATE_MACHINE_STARTED) { + services.vaultService.rawUpdates.subscribe { + if (insertionType == InsertionType.ENTITY_MANAGER) { + services.withEntityManager { + persist(entityWithIdOne) + persist(entityWithIdTwo) + persist(entityWithIdThree) + } + } else { + services.jdbcSession().run { + insert(entityWithIdOne) + insert(entityWithIdTwo) + insert(entityWithIdThree) } } } diff --git a/node/src/integration-test/kotlin/net/corda/node/services/CordaServiceLifecycleFatalTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/CordaServiceLifecycleFatalTests.kt index a8b19e7d91..35c1352c7a 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/CordaServiceLifecycleFatalTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/CordaServiceLifecycleFatalTests.kt @@ -51,12 +51,14 @@ class CordaServiceLifecycleFatalTests { object FailingObserver : ServiceLifecycleObserver { override fun onServiceLifecycleEvent(event: ServiceLifecycleEvent) { - val tmpFile = File(System.getProperty(tempFilePropertyName)) - tmpFile.appendText("\n" + readyToThrowMarker) - eventually(duration = 30.seconds) { - assertEquals(goodToThrowMarker, tmpFile.readLines().last()) + if (event == ServiceLifecycleEvent.STATE_MACHINE_STARTED) { + val tmpFile = File(System.getProperty(tempFilePropertyName)) + tmpFile.appendText("\n" + readyToThrowMarker) + eventually(duration = 30.seconds) { + assertEquals(goodToThrowMarker, tmpFile.readLines().last()) + } + throw CordaServiceCriticalFailureException("controlled failure") } - throw CordaServiceCriticalFailureException("controlled failure") } } } diff --git a/node/src/integration-test/kotlin/net/corda/node/services/CordaServiceLifecycleTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/CordaServiceLifecycleTests.kt index 9530cb0af2..e615e91a60 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/CordaServiceLifecycleTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/CordaServiceLifecycleTests.kt @@ -3,18 +3,23 @@ package net.corda.node.services import co.paralleluniverse.fibers.Suspendable import net.corda.core.flows.FlowLogic import net.corda.core.flows.StartableByRPC +import net.corda.core.flows.StartableByService import net.corda.core.messaging.startFlow import net.corda.core.node.AppServiceHub import net.corda.core.node.services.CordaService import net.corda.core.node.services.ServiceLifecycleEvent +import net.corda.core.node.services.ServiceLifecycleEvent.BEFORE_STATE_MACHINE_START import net.corda.core.node.services.ServiceLifecycleEvent.STATE_MACHINE_STARTED import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.utilities.getOrThrow import net.corda.testing.core.ALICE_NAME import net.corda.testing.driver.DriverParameters +import net.corda.testing.driver.InProcess import net.corda.testing.driver.driver import net.corda.testing.node.internal.enclosedCordapp +import org.junit.Before import org.junit.Test + import kotlin.test.assertEquals class CordaServiceLifecycleTests { @@ -22,23 +27,70 @@ class CordaServiceLifecycleTests { private companion object { const val TEST_PHRASE = "testPhrase" + // the number of times to register a service callback + private var numServiceCallbacks = 0 + // the set of events a test wants to capture + private var eventsToBeCaptured: MutableSet = mutableSetOf() + // the events that were actually captured in a test private val eventsCaptured: MutableList = mutableListOf() + + } + + @Before + fun setup() { + numServiceCallbacks = 1 + eventsCaptured.clear() + eventsToBeCaptured = setOf(BEFORE_STATE_MACHINE_START, STATE_MACHINE_STARTED).toMutableSet() } @Test(timeout=300_000) fun `corda service receives events`() { - eventsCaptured.clear() val result = driver(DriverParameters(startNodesInProcess = true, cordappsForAllNodes = listOf(enclosedCordapp()), notarySpecs = emptyList())) { val node = startNode(providedName = ALICE_NAME).getOrThrow() node.rpc.startFlow(::ComputeTextLengthThroughCordaService, TEST_PHRASE).returnValue.getOrThrow() } + val expectedEventsAndTheOrderTheyOccurIn = listOf(BEFORE_STATE_MACHINE_START, STATE_MACHINE_STARTED) assertEquals(TEST_PHRASE.length, result) - assertEquals(1, eventsCaptured.size) - assertEquals(listOf(STATE_MACHINE_STARTED), eventsCaptured) + assertEquals(numServiceCallbacks * 2, eventsCaptured.size) + assertEquals(expectedEventsAndTheOrderTheyOccurIn, eventsCaptured) + } + + @Test(timeout=300_000) + fun `corda service receives BEFORE_STATE_MACHINE_START before the state machine is started`() { + testStateMachineManagerStatusWhenServiceEventOccurs( + event = BEFORE_STATE_MACHINE_START, + expectedResult = TestSmmStateService.STATE_MACHINE_MANAGER_WAS_NOT_STARTED + ) + } + + @Test(timeout=300_000) + fun `corda service receives STATE_MACHINE_STARTED after the state machine is started`() { + testStateMachineManagerStatusWhenServiceEventOccurs( + event = STATE_MACHINE_STARTED, + expectedResult = TestSmmStateService.STATE_MACHINE_MANAGER_WAS_STARTED + ) + } + + /** + * Commonised + */ + private fun testStateMachineManagerStatusWhenServiceEventOccurs(event: ServiceLifecycleEvent, expectedResult : Int) { + val result = driver(DriverParameters(startNodesInProcess = true, cordappsForAllNodes = listOf(enclosedCordapp()), + notarySpecs = emptyList())) { + val node = startNode(providedName = ALICE_NAME).getOrThrow() + if (node is InProcess) { // assuming the node-handle is always one of these + val svc = node.services.cordaService(TestSmmStateService::class.java) + svc.getSmmStartedForEvent(event) + } else { + TestSmmStateService.STATE_MACHINE_MANAGER_UNKNOWN_STATUS + } + } + assertEquals(expectedResult, result) } @StartableByRPC + @StartableByService class ComputeTextLengthThroughCordaService(private val text: String) : FlowLogic() { @Suspendable override fun call(): Int { @@ -52,17 +104,14 @@ class CordaServiceLifecycleTests { class TextLengthComputingService(services: AppServiceHub) : SingletonSerializeAsToken() { init { - services.register { addEvent(it) } + for (n in 1..numServiceCallbacks) { + services.register { addEvent(it) } + } } private fun addEvent(event: ServiceLifecycleEvent) { - when (event) { - STATE_MACHINE_STARTED -> { - eventsCaptured.add(event) - } - else -> { - eventsCaptured.add(event) - } + if (event in eventsToBeCaptured) { + eventsCaptured.add(event) } } @@ -71,4 +120,42 @@ class CordaServiceLifecycleTests { return text.length } } + + /** + * Service that checks the State Machine Manager state (started, not started) when service events are received. + */ + @CordaService + class TestSmmStateService(private val services: AppServiceHub) : SingletonSerializeAsToken() { + + companion object { + const val STATE_MACHINE_MANAGER_UNKNOWN_STATUS = -1 + const val STATE_MACHINE_MANAGER_WAS_NOT_STARTED = 0 + const val STATE_MACHINE_MANAGER_WAS_STARTED = 1 + } + + var smmStateAtEvent = mutableMapOf() + + init { + services.register { addEvent(it) } + } + + private fun addEvent(event: ServiceLifecycleEvent) { + smmStateAtEvent[event] = checkSmmStarted() + } + + private fun checkSmmStarted() : Int { + // try to start a flow; success == SMM started + try { + services.startFlow(ComputeTextLengthThroughCordaService(TEST_PHRASE)).returnValue.getOrThrow() + return STATE_MACHINE_MANAGER_WAS_STARTED + } catch (ex : UninitializedPropertyAccessException) { + return STATE_MACHINE_MANAGER_WAS_NOT_STARTED + } + } + + /** + * Given an event, was the SMM started when the event was received? + */ + fun getSmmStartedForEvent(event: ServiceLifecycleEvent) : Int = smmStateAtEvent.getOrDefault(event, STATE_MACHINE_MANAGER_UNKNOWN_STATUS) + } } \ 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 705d5dc447..53b1aa9bdc 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -639,6 +639,11 @@ abstract class AbstractNode(val configuration: NodeConfiguration, tokenizableServices = null verifyCheckpointsCompatible(frozenTokenizableServices) + /* Note the .get() at the end of the distributeEvent call, below. + This will block until all Corda Services have returned from processing the event, allowing a service to prevent the + state machine manager from starting (just below this) until the service is ready. + */ + nodeLifecycleEventsDistributor.distributeEvent(NodeLifecycleEvent.BeforeStateMachineStart(nodeServicesContext)).get() val callback = smm.start(frozenTokenizableServices) val smmStartedFuture = rootFuture.map { callback() } // Shut down the SMM so no Fibers are scheduled. diff --git a/node/src/main/kotlin/net/corda/node/internal/AppServiceHubImpl.kt b/node/src/main/kotlin/net/corda/node/internal/AppServiceHubImpl.kt index 922316045b..5acf706f91 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AppServiceHubImpl.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AppServiceHubImpl.kt @@ -45,6 +45,10 @@ internal class AppServiceHubImpl(private val serviceHub: S observer.onServiceLifecycleEvent(ServiceLifecycleEvent.STATE_MACHINE_STARTED) reportSuccess(nodeLifecycleEvent) } + is NodeLifecycleEvent.BeforeStateMachineStart<*> -> Try.on { + observer.onServiceLifecycleEvent(ServiceLifecycleEvent.BEFORE_STATE_MACHINE_START) + reportSuccess(nodeLifecycleEvent) + } else -> super.update(nodeLifecycleEvent) } } From 491d37e2b1578fe1942c74e3c176aa3fcadaa902 Mon Sep 17 00:00:00 2001 From: peterli-r3 <51169685+peterli-r3@users.noreply.github.com> Date: Mon, 13 Jun 2022 16:53:12 +0800 Subject: [PATCH 36/93] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c22243385..d85fe34e46 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ However, like all things, Corda must evolve to serve the more stringent needs of * [Documentation](https://docs.corda.net) * [Stack Overflow Tag](https://stackoverflow.com/questions/tagged/corda) * [Slack Channel](https://slack.corda.net/) -* [Twitter](https://twitter.com/cordadlt) +* [Twitter](https://twitter.com/Cordablockchain) * [Meetups](https://www.meetup.com/pro/corda/) * [Training Courses](https://www.corda.net/corda-training/) From c57bbd1c3938608ec51537c1676ec4c72a3a9a72 Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Tue, 14 Jun 2022 17:15:31 +0100 Subject: [PATCH 37/93] Added integration tests for service event priorities --- .../services/CordaServicePriorityTests.kt | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 node/src/integration-test/kotlin/net/corda/node/services/CordaServicePriorityTests.kt diff --git a/node/src/integration-test/kotlin/net/corda/node/services/CordaServicePriorityTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/CordaServicePriorityTests.kt new file mode 100644 index 0000000000..3d5d82359e --- /dev/null +++ b/node/src/integration-test/kotlin/net/corda/node/services/CordaServicePriorityTests.kt @@ -0,0 +1,132 @@ +package net.corda.node.services + +import net.corda.core.node.AppServiceHub +import net.corda.core.node.AppServiceHub.Companion.SERVICE_PRIORITY_HIGH +import net.corda.core.node.AppServiceHub.Companion.SERVICE_PRIORITY_LOW +import net.corda.core.node.AppServiceHub.Companion.SERVICE_PRIORITY_NORMAL +import net.corda.core.node.services.CordaService +import net.corda.core.node.services.ServiceLifecycleEvent +import net.corda.core.serialization.SingletonSerializeAsToken +import net.corda.core.utilities.getOrThrow +import net.corda.testing.core.ALICE_NAME +import net.corda.testing.driver.DriverParameters +import net.corda.testing.driver.driver +import net.corda.testing.node.internal.enclosedCordapp +import org.junit.Before +import org.junit.Test +import kotlin.test.assertEquals + +/** + * Test the priorities of Corda services when distributing/handlimg service events. + * Services register themselves with a priority - an integer whereby higher numbers == higher priority. + * There are a few pre-defined priorities provided by Corda: + * SERVICE_PRIORITY_HIGH + * SERVICE_PRIORITY_NORMAL + * SERVICE_PRIORITY_LOW + * + * but actually the priority can be ANY integer the Corda service desires. + */ + +/** + * This base class commonizes code for the subsequent real test classes, further down. + */ +open class CordaServicePriorityTests { + companion object { + val eventsCaptured: MutableMap> = mutableMapOf() + } + + /** + * Services loaded by the node + */ + open class PriorityService(private val services: AppServiceHub, private val priority : Int, private val name : String) : SingletonSerializeAsToken() { + init { + services.register(priority = priority) { addEvent(it) } + } + + private fun addEvent(event: ServiceLifecycleEvent) { + eventsCaptured.getOrPut(event) { + mutableListOf() + }.add(name) + } + } + + @Before + fun startUp() { + driver(DriverParameters(startNodesInProcess = true, cordappsForAllNodes = listOf(enclosedCordapp()), + notarySpecs = emptyList())) { + startNode(providedName = ALICE_NAME).getOrThrow() + } + } +} + +/** + * Test the priorities of Corda services when distributing/handlimg service events where services have different priorities. + * + * The expectation is that service events BEFORE_STATE_MACHINE_START and STATE_MACHINE_STARTED are delivered to Corda Services + * in priority order. That is, services registered with a higher priority value are sent the events first. + */ +class CordaServiceDifferentPriorityTests : CordaServicePriorityTests() { + + @Test(timeout=300_000) + @Suppress("unused") + fun `startup service events are delivered to Corda Services in priority order`() { + // expect events to be delivered to these Corda Services in this order + val expectedCallList = listOf("John", "Paul", "George", "Ringo") + + assertEquals(expectedCallList, eventsCaptured[ServiceLifecycleEvent.BEFORE_STATE_MACHINE_START]?.toList()) + assertEquals(expectedCallList, eventsCaptured[ServiceLifecycleEvent.STATE_MACHINE_STARTED]?.toList()) + } + + + /* + These are the services with different priorities. + */ + @CordaService + class John(val services: AppServiceHub) : PriorityService(services, priority = SERVICE_PRIORITY_HIGH, name = "John") + + @CordaService + class Paul(val services: AppServiceHub) : PriorityService(services, priority = SERVICE_PRIORITY_HIGH - 1, name = "Paul") + + @CordaService + class George(val services: AppServiceHub) : PriorityService(services, priority = SERVICE_PRIORITY_NORMAL, name = "George") + + @CordaService + class Ringo(val services: AppServiceHub) : PriorityService(services, priority = SERVICE_PRIORITY_LOW, name = "Ringo") +} + + + +/** + * Test the priorities of Corda services when distributing/handlimg service events where services have the same priorities. + * + * The expectation is that service events BEFORE_STATE_MACHINE_START and STATE_MACHINE_STARTED are delivered to all Corda Services + * but the order of delivery is not defined, and may differ from run to run. + */ +class CordaServiceSamePriorityTests : CordaServicePriorityTests() { + + @Test(timeout=300_000) + @Suppress("unused") + fun `startup service events are delivered to all equal-priority services, the ordering is not fixed`() { + // expect the service events to be delivered to these Corda Services, but don;t care about the order. + val expectedCallList = listOf("Pete", "Roger", "John", "Keith") + + assertEquals(expectedCallList.sorted(), eventsCaptured[ServiceLifecycleEvent.BEFORE_STATE_MACHINE_START]?.toList()?.sorted()) + assertEquals(expectedCallList.sorted(), eventsCaptured[ServiceLifecycleEvent.STATE_MACHINE_STARTED]?.toList()?.sorted()) + } + + + /* + These are the services with all the same priority. + */ + @CordaService + class Pete(val services: AppServiceHub) : PriorityService(services, priority = SERVICE_PRIORITY_NORMAL, name = "Pete") + + @CordaService + class Roger(val services: AppServiceHub) : PriorityService(services, priority = SERVICE_PRIORITY_NORMAL, name = "Roger") + + @CordaService + class John(val services: AppServiceHub) : PriorityService(services, priority = SERVICE_PRIORITY_NORMAL, name = "John") + + @CordaService + class Keith(val services: AppServiceHub) : PriorityService(services, priority = SERVICE_PRIORITY_NORMAL, name = "Keith") +} \ No newline at end of file From 199f635d694afbdd64f0c6c6a8b9e4b07d5ae156 Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Wed, 15 Jun 2022 11:56:03 +0100 Subject: [PATCH 38/93] Attempt to fix service priority tests when they are run on Jenkins --- .../kotlin/net/corda/node/services/CordaServicePriorityTests.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/CordaServicePriorityTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/CordaServicePriorityTests.kt index 3d5d82359e..c873555981 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/CordaServicePriorityTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/CordaServicePriorityTests.kt @@ -52,6 +52,7 @@ open class CordaServicePriorityTests { @Before fun startUp() { + eventsCaptured.clear() driver(DriverParameters(startNodesInProcess = true, cordappsForAllNodes = listOf(enclosedCordapp()), notarySpecs = emptyList())) { startNode(providedName = ALICE_NAME).getOrThrow() From 3d52a67ded6cf9d3fb1374d72435c71e3e58da37 Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Wed, 22 Jun 2022 16:20:03 +0100 Subject: [PATCH 39/93] ENT-6863 upgrade netty to 4.1.77.Final --- constants.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/constants.properties b/constants.properties index 87362e8311..177ff91cd9 100644 --- a/constants.properties +++ b/constants.properties @@ -1,6 +1,7 @@ # This file is parsed from Python in the docs/source/conf.py file # because some versions here need to be matched by app authors in # their own projects. So don't get fancy with syntax! +# Fancy syntax - multi pass ${whatever} replacement cordaVersion=4.10 versionSuffix=SNAPSHOT @@ -55,7 +56,7 @@ assertjVersion=3.12.2 slf4JVersion=1.7.30 log4JVersion=2.17.1 okhttpVersion=3.14.2 -nettyVersion=4.1.76.Final +nettyVersion=4.1.77.Final fileuploadVersion=1.4 kryoVersion=4.0.2 kryoSerializerVersion=0.43 From 54fdd12a2d20a85e7945ce61dde055c60578ad45 Mon Sep 17 00:00:00 2001 From: Chris Cochrane <78791827+chriscochrane@users.noreply.github.com> Date: Thu, 7 Jul 2022 12:33:51 +0100 Subject: [PATCH 40/93] ENT-6866 support quick RPCs that are not processed via the RPC thread pool (#7213) * ENT-6866 support quick RPCs that are not processed via the RPC thread pool --- .../corda/client/rpc/QuickRPCRequestTests.kt | 109 ++++++++++++++++++ .../net/corda/node/services/rpc/RPCServer.kt | 54 ++++++++- 2 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 client/rpc/src/test/kotlin/net/corda/client/rpc/QuickRPCRequestTests.kt diff --git a/client/rpc/src/test/kotlin/net/corda/client/rpc/QuickRPCRequestTests.kt b/client/rpc/src/test/kotlin/net/corda/client/rpc/QuickRPCRequestTests.kt new file mode 100644 index 0000000000..22110edafc --- /dev/null +++ b/client/rpc/src/test/kotlin/net/corda/client/rpc/QuickRPCRequestTests.kt @@ -0,0 +1,109 @@ +package net.corda.client.rpc + +import net.corda.core.crypto.random63BitValue +import net.corda.core.internal.concurrent.fork +import net.corda.core.messaging.RPCOps +import net.corda.core.utilities.millis +import net.corda.coretesting.internal.testThreadFactory +import net.corda.node.services.rpc.RPCServerConfiguration +import net.corda.testing.node.internal.RPCDriverDSL +import net.corda.testing.node.internal.rpcDriver +import org.junit.After +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.CountDownLatch +import java.util.concurrent.Executors +import kotlin.test.assertTrue + +@RunWith(Parameterized::class) +class QuickRPCRequestTests : AbstractRPCTest() { + + companion object { + // indicate when all RPC threads are busy + val threadBusyLatches = ConcurrentHashMap() + + val numRpcThreads = 4 + } + + interface TestOps : RPCOps { + fun newLatch(numberOfDowns: Int): Long + fun waitLatch(id: Long) + fun downLatch(id: Long) + } + + class TestOpsImpl : TestOps { + private val latches = ConcurrentHashMap() + override val protocolVersion = 1000 + + override fun newLatch(numberOfDowns: Int): Long { + val id = random63BitValue() + val latch = CountDownLatch(numberOfDowns) + latches[id] = latch + return id + } + + override fun waitLatch(id: Long) { + threadBusyLatches[id]!!.countDown() + latches[id]!!.await() + } + + override fun downLatch(id: Long) { + latches[id]!!.countDown() + } + } + + private fun RPCDriverDSL.testProxy(): TestProxy { + return testProxy( + TestOpsImpl(), + clientConfiguration = CordaRPCClientConfiguration.DEFAULT.copy( + reapInterval = 100.millis + ), + serverConfiguration = RPCServerConfiguration.DEFAULT.copy( + rpcThreadPoolSize = numRpcThreads + ) + ) + } + + private val pool = Executors.newFixedThreadPool(10, testThreadFactory()) + @After + fun shutdown() { + pool.shutdown() + } + + @Test(timeout=300_000) + fun `quick RPCs by-pass the standard RPC thread pool`() { + /* + 1. Set up a node with N RPC threads + 2. Send a call to a blocking RPC on each thread + 3. When all RPC threads are blocked, call a quick RPC + 4. Check the quick RPC returns, whilst the RPC threads are still blocked + */ + rpcDriver { + val proxy = testProxy() + val numberOfDownsRequired = 1 + val id = proxy.ops.newLatch(numberOfDownsRequired) + + val newThreadLatch = CountDownLatch(numRpcThreads) + threadBusyLatches[id] = newThreadLatch + + // Flood the RPC threads with blocking calls + for (n in 1..numRpcThreads) { + pool.fork { + proxy.ops.waitLatch(id) + } + } + // wait until all the RPC threads are blocked + threadBusyLatches[id]!!.await() + // try a quick RPC - getProtocolVersion() is always quick + val quickResult = proxy.ops.protocolVersion.toString() + + // the fact that a result is returned is proof enough that the quick-RPC has by-passed the + // flooded RPC thread pool + assertTrue(quickResult.isNotEmpty()) + + // The failure condition is that the test times out. + } + } +} \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/services/rpc/RPCServer.kt b/node/src/main/kotlin/net/corda/node/services/rpc/RPCServer.kt index fdda466c2d..2b1b344aad 100644 --- a/node/src/main/kotlin/net/corda/node/services/rpc/RPCServer.kt +++ b/node/src/main/kotlin/net/corda/node/services/rpc/RPCServer.kt @@ -63,6 +63,7 @@ import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit +import java.util.function.Predicate import kotlin.concurrent.thread private typealias ObservableSubscriptionMap = Cache @@ -359,6 +360,22 @@ class RPCServer( } private fun clientArtemisMessageHandler(artemisMessage: ClientMessage) { + + /* + Local function for actually executing an RPC, either directly or through the thread pool + */ + fun executeRpc(context : RpcAuthContext, clientToServer : RPCApi.ClientToServer.RpcRequest, arguments : Try.Success>, isQuickRpc : Boolean) { + if (isQuickRpc) { + val result = invokeRpc(context, clientToServer.methodName, arguments.value) + sendReply(clientToServer.replyId, clientToServer.clientAddress, result) + } else { + rpcExecutor!!.submit { + val result = invokeRpc(context, clientToServer.methodName, arguments.value) + sendReply(clientToServer.replyId, clientToServer.clientAddress, result) + } + } + } + lifeCycle.requireState(State.STARTED) val clientToServer = RPCApi.ClientToServer.fromClientMessage(artemisMessage) if (log.isDebugEnabled) { @@ -387,16 +404,45 @@ class RPCServer( val arguments = Try.on { clientToServer.serialisedArguments.deserialize>(context = RPC_SERVER_CONTEXT) } + log.debug("Received RPC request for [${clientToServer.methodName}]") + + /* + The supplied method name may consist of #. + If just a method name is supplied then it is a call made via CordaRPCOps because a quirk of the + stored method names is that CordaRPCOps methods are stored without their class name. + + The list of predicates below describes how to match quick RPC methods. + If at least one predicate returns true for the supplied method then it is treated as + a quick RPC. + */ + val quickRpcsList = listOf>( + // getProtocolVersion for any class + Predicate() { req -> + req.methodName.substringAfter(CLASS_METHOD_DIVIDER) == "getProtocolVersion" + }, + // currentNodeTime for CordaRPCOps + Predicate() { req -> + req.methodName == "currentNodeTime" + } + // Add more predicates as and when needed + ) + + val isQuickRpc = if (quickRpcsList.any { + it.test(clientToServer) + }) { + log.debug("Handling [${clientToServer.methodName}] as a quick RPC") + true + } else { + false + } + val context: RpcAuthContext when (arguments) { is Try.Success -> { context = artemisMessage.context(clientToServer.sessionId, arguments.value) context.invocation.pushToLoggingContext() log.debug { "Arguments: ${arguments.value.toTypedArray().contentDeepToString()}" } - rpcExecutor!!.submit { - val result = invokeRpc(context, clientToServer.methodName, arguments.value) - sendReply(clientToServer.replyId, clientToServer.clientAddress, result) - } + executeRpc(context, clientToServer, arguments, isQuickRpc) } is Try.Failure -> { context = artemisMessage.context(clientToServer.sessionId, emptyList()) From cc929e3b5b17593f908188677cfb42bbd1090b7a Mon Sep 17 00:00:00 2001 From: ronanbrowne88 Date: Sun, 10 Jul 2022 19:33:37 +0100 Subject: [PATCH 41/93] INFRA-1805 add snyk scanning to corda os 4.4 --- .ci/dev/regression/Jenkinsfile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index dc1c04a526..2c037b5876 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -83,6 +83,7 @@ pipeline { CORDA_BUILD_EDITION = "${buildEdition}" DOCKER_URL = "https://index.docker.io/v1/" EMAIL_RECIPIENTS = credentials('corda4-email-recipient') + SNYK_API_KEY = "c4-os-snyk" } stages { @@ -192,6 +193,15 @@ pipeline { } } + stage('Snyk Security') { + when { + expression { isReleaseTag || isReleaseCandidate || isReleaseBranch } + } + steps { + snykSecurityScan("${env.SNYK_API_KEY}", "--all-sub-projects --prune-repeated-subdependencies --debug --target-reference='${env.BRANCH_NAME}' --project-tags=Branch='${env.BRANCH_NAME.replaceAll("[^0-9|a-z|A-Z]+","_")}'") + } + } + stage('All Tests') { when { expression { params.DO_TEST } From 212cd2214cfb5e5067b9e3c51f7413f1cdad211a Mon Sep 17 00:00:00 2001 From: ronanbrowne88 Date: Mon, 11 Jul 2022 22:01:25 +0100 Subject: [PATCH 42/93] CORE-4769 add snyk scan open source 4.4 --- .ci/dev/regression/Jenkinsfile | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 2c037b5876..6e0959b2e1 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -468,15 +468,20 @@ pipeline { } } success { - script { - sendSlackNotifications("good", "BUILD PASSED", false, "#corda-corda4-open-source-build-notifications") - - } + script { + sendSlackNotifications("good", "BUILD PASSED", false, "#corda-corda4-open-source-build-notifications") + if (isReleaseTag || isReleaseCandidate || isReleaseBranch) { + snykSecurityScan.generateHtmlElements() + } + } } unstable { - script { - sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", false, "#corda-corda4-open-source-build-notifications") - } + script { + sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", false, "#corda-corda4-open-source-build-notifications") + if (isReleaseTag || isReleaseCandidate || isReleaseBranch) { + snykSecurityScan.generateHtmlElements() + } + } } failure { script { From 14e2ef347899b7f2dde910d95d54ed0e66dc2726 Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Thu, 18 Aug 2022 13:02:20 +0100 Subject: [PATCH 43/93] Updated KDoc for quick RPCs --- .../src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt | 6 +++++- core/src/main/kotlin/net/corda/core/messaging/RPCOps.kt | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt index c2351baa4c..b2816cf04c 100644 --- a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt +++ b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt @@ -392,7 +392,11 @@ interface CordaRPCOps : RPCOps { /** Queries attachments metadata */ fun queryAttachments(query: AttachmentQueryCriteria, sorting: AttachmentSort?): List - /** Returns the node's current time. */ + /** Returns the node's current time. + * + * Is a quick RPC, meaning that it is handled outside the node's standard thread pool in order to provide a + * quick response even when the node is dealing with a high volume of RPC calls. + */ fun currentNodeTime(): Instant /** diff --git a/core/src/main/kotlin/net/corda/core/messaging/RPCOps.kt b/core/src/main/kotlin/net/corda/core/messaging/RPCOps.kt index e6aa0b79a4..e4e1416e13 100644 --- a/core/src/main/kotlin/net/corda/core/messaging/RPCOps.kt +++ b/core/src/main/kotlin/net/corda/core/messaging/RPCOps.kt @@ -8,6 +8,10 @@ import net.corda.core.DoNotImplement */ @DoNotImplement interface RPCOps { - /** Returns the RPC protocol version. Exists since version 0 so guaranteed to be present. */ + /** Returns the RPC protocol version. Exists since version 0 so guaranteed to be present. + * + * Getting this property is handled as a quick RPC, meaning that it is handled outside the node's standard + * thread pool in order to provide a quick response even when the node is dealing with a high volume of RPC calls. + */ val protocolVersion: Int } \ No newline at end of file From 293af38e2899653b9610fb4bac9488fba106e03e Mon Sep 17 00:00:00 2001 From: JanSzkaradek Date: Thu, 18 Aug 2022 15:58:17 +0100 Subject: [PATCH 44/93] changed snyk scan target --- .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 6e0959b2e1..20822ca1f5 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -198,7 +198,7 @@ pipeline { expression { isReleaseTag || isReleaseCandidate || isReleaseBranch } } steps { - snykSecurityScan("${env.SNYK_API_KEY}", "--all-sub-projects --prune-repeated-subdependencies --debug --target-reference='${env.BRANCH_NAME}' --project-tags=Branch='${env.BRANCH_NAME.replaceAll("[^0-9|a-z|A-Z]+","_")}'") + snykSecurityScan("${env.SNYK_API_KEY}", "--sub-project=node --prune-repeated-subdependencies --debug --target-reference='${env.BRANCH_NAME}' --project-tags=Branch='${env.BRANCH_NAME.replaceAll("[^0-9|a-z|A-Z]+","_")}'") } } From 1e5b18c3b78668c326cc4e0b3c75cbcf78856081 Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Fri, 19 Aug 2022 14:22:32 +0100 Subject: [PATCH 45/93] NOTICK: scan runtime classpath --- .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 20822ca1f5..ce63250f29 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -198,7 +198,7 @@ pipeline { expression { isReleaseTag || isReleaseCandidate || isReleaseBranch } } steps { - snykSecurityScan("${env.SNYK_API_KEY}", "--sub-project=node --prune-repeated-subdependencies --debug --target-reference='${env.BRANCH_NAME}' --project-tags=Branch='${env.BRANCH_NAME.replaceAll("[^0-9|a-z|A-Z]+","_")}'") + snykSecurityScan("${env.SNYK_API_KEY}", "--sub-project=node --configuration-matching='^runtimeClasspath\$' --prune-repeated-subdependencies --debug --target-reference='${env.BRANCH_NAME}' --project-tags=Branch='${env.BRANCH_NAME.replaceAll("[^0-9|a-z|A-Z]+","_")}'") } } From 8afcf57e387570fd0b666959a3fb5c17fea4301d Mon Sep 17 00:00:00 2001 From: Ronan Browne Date: Mon, 22 Aug 2022 19:28:37 +0100 Subject: [PATCH 46/93] INFRA-1844: tidy up and expand scanning of projects --- .ci/dev/regression/Jenkinsfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index ce63250f29..528ebf4909 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -198,7 +198,12 @@ pipeline { expression { isReleaseTag || isReleaseCandidate || isReleaseBranch } } steps { - snykSecurityScan("${env.SNYK_API_KEY}", "--sub-project=node --configuration-matching='^runtimeClasspath\$' --prune-repeated-subdependencies --debug --target-reference='${env.BRANCH_NAME}' --project-tags=Branch='${env.BRANCH_NAME.replaceAll("[^0-9|a-z|A-Z]+","_")}'") + script { + // Invoke Snyk for each Gradle sub project we wish to scan + def modulesToScan = ['node', 'capsule'] + modulesToScan.each { module -> + snykSecurityScan("${env.SNYK_API_KEY}", "--sub-project=$module --configuration-matching='^runtimeClasspath\$' --prune-repeated-subdependencies --debug --target-reference='${env.BRANCH_NAME}' --project-tags=Branch='${env.BRANCH_NAME.replaceAll("[^0-9|a-z|A-Z]+","_")}'") + } } } From eb50c8d22ed2ab9eee5efd6c843b987a3f2ec4f5 Mon Sep 17 00:00:00 2001 From: Jan Szkaradek Date: Fri, 2 Sep 2022 13:15:36 +0100 Subject: [PATCH 47/93] added modules for snyk scanning (#7236) --- .ci/dev/regression/Jenkinsfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 528ebf4909..a4d10a07e4 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -200,10 +200,11 @@ pipeline { steps { script { // Invoke Snyk for each Gradle sub project we wish to scan - def modulesToScan = ['node', 'capsule'] + def modulesToScan = ['node', 'capsule', 'bridge', 'bridgecapsule'] modulesToScan.each { module -> snykSecurityScan("${env.SNYK_API_KEY}", "--sub-project=$module --configuration-matching='^runtimeClasspath\$' --prune-repeated-subdependencies --debug --target-reference='${env.BRANCH_NAME}' --project-tags=Branch='${env.BRANCH_NAME.replaceAll("[^0-9|a-z|A-Z]+","_")}'") - } + } + } } } From f24fa96a53524ebf6ef74216085dde15c23a9cd6 Mon Sep 17 00:00:00 2001 From: Khoi Nguyen Date: Fri, 9 Sep 2022 16:20:56 +0100 Subject: [PATCH 48/93] INFRA-1856: Update pr scanner version * Updated version use by pr scanner to v1.6.1 --- .github/workflows/check-pr-title.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-pr-title.yml b/.github/workflows/check-pr-title.yml index a27b6c02e4..544a41c54c 100644 --- a/.github/workflows/check-pr-title.yml +++ b/.github/workflows/check-pr-title.yml @@ -7,7 +7,7 @@ jobs: check-pr-title: runs-on: ubuntu-latest steps: - - uses: morrisoncole/pr-lint-action@v1.4.1 + - uses: morrisoncole/pr-lint-action@v1.6.1 with: title-regex: '^((CORDA|AG|EG|ENT|INFRA|NAAS)-\d+|NOTICK)(.*)' on-failed-regex-comment: "PR title failed to match regex -> `%regex%`" From 5ca5b8d0965f2d30244d439a5eb0418c46733d11 Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Tue, 13 Sep 2022 11:41:19 +0100 Subject: [PATCH 49/93] Do not black-list AMQP targets that suffer a handshake failure --- .../protonwrapper/netty/AMQPChannelHandler.kt | 12 +- .../protonwrapper/netty/AMQPClient.kt | 73 ++++++++++-- .../protonwrapper/netty/ConnectionChange.kt | 6 +- .../protonwrapper/netty/ConnectionResult.kt | 6 + .../node/amqp/AMQPClientSslErrorsTest.kt | 4 +- .../net/corda/node/amqp/ProtonWrapperTests.kt | 108 +++++++++++++++++- 6 files changed, 183 insertions(+), 26 deletions(-) create mode 100644 node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/ConnectionResult.kt diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPChannelHandler.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPChannelHandler.kt index c4a4e8ebb8..4cba1c6d95 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPChannelHandler.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPChannelHandler.kt @@ -58,7 +58,7 @@ internal class AMQPChannelHandler(private val serverMode: Boolean, private var remoteCert: X509Certificate? = null private var eventProcessor: EventProcessor? = null private var suppressClose: Boolean = false - private var badCert: Boolean = false + private var connectionResult: ConnectionResult = ConnectionResult.NO_ERROR private var localCert: X509Certificate? = null private var requestedServerName: String? = null @@ -131,7 +131,7 @@ internal class AMQPChannelHandler(private val serverMode: Boolean, val ch = ctx.channel() logInfoWithMDC { "Closed client connection ${ch.id()} from $remoteAddress to ${ch.localAddress()}" } if (!suppressClose) { - onClose(ch as SocketChannel, ConnectionChange(remoteAddress, remoteCert, false, badCert)) + onClose(ch as SocketChannel, ConnectionChange(remoteAddress, remoteCert, false, connectionResult)) } eventProcessor?.close() ctx.fireChannelInactive() @@ -274,13 +274,13 @@ internal class AMQPChannelHandler(private val serverMode: Boolean, val remoteX500Name = try { CordaX500Name.build(remoteCert!!.subjectX500Principal) } catch (ex: IllegalArgumentException) { - badCert = true + connectionResult = ConnectionResult.HANDSHAKE_FAILURE logErrorWithMDC("Certificate subject not a valid CordaX500Name", ex) ctx.close() return } if (allowedRemoteLegalNames != null && remoteX500Name !in allowedRemoteLegalNames) { - badCert = true + connectionResult = ConnectionResult.HANDSHAKE_FAILURE logErrorWithMDC("Provided certificate subject $remoteX500Name not in expected set $allowedRemoteLegalNames") ctx.close() return @@ -288,7 +288,7 @@ internal class AMQPChannelHandler(private val serverMode: Boolean, logInfoWithMDC { "Handshake completed with subject: $remoteX500Name, requested server name: ${sslHandler.getRequestedServerName()}." } createAMQPEngine(ctx) - onOpen(ctx.channel() as SocketChannel, ConnectionChange(remoteAddress, remoteCert, connected = true, badCert = false)) + onOpen(ctx.channel() as SocketChannel, ConnectionChange(remoteAddress, remoteCert, connected = true, connectionResult = ConnectionResult.NO_ERROR)) } private fun handleFailedHandshake(ctx: ChannelHandlerContext, evt: SslHandshakeCompletionEvent) { @@ -303,7 +303,7 @@ internal class AMQPChannelHandler(private val serverMode: Boolean, // io.netty.handler.ssl.SslHandler.setHandshakeFailureTransportFailure() cause is SSLException && (cause.message?.contains("writing TLS control frames") == true) -> logWarnWithMDC(cause.message!!) cause is SSLException && (cause.message?.contains("internal_error") == true) -> logWarnWithMDC("Received internal_error during handshake") - else -> badCert = true + else -> connectionResult = ConnectionResult.HANDSHAKE_FAILURE } logWarnWithMDC("Handshake failure: ${evt.cause().message}") if (log.isTraceEnabled) { diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPClient.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPClient.kt index 4551608054..4c8b78d57f 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPClient.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPClient.kt @@ -26,6 +26,7 @@ import rx.Observable import rx.subjects.PublishSubject import java.lang.Long.min import java.net.InetSocketAddress +import java.time.Duration import java.util.concurrent.TimeUnit import java.util.concurrent.locks.ReentrantLock import javax.net.ssl.KeyManagerFactory @@ -70,6 +71,7 @@ class AMQPClient(val targets: List, private const val MAX_RETRY_INTERVAL = 60000L private const val BACKOFF_MULTIPLIER = 2L private val NUM_CLIENT_THREADS = Integer.getInteger(CORDA_AMQP_NUM_CLIENT_THREAD_PROP_NAME, 2) + private val handshakeRetryIntervals = List(5) { Duration.ofMinutes(5) } } private val lock = ReentrantLock() @@ -82,7 +84,9 @@ class AMQPClient(val targets: List, private var targetIndex = 0 private var currentTarget: NetworkHostAndPort = targets.first() private var retryInterval = MIN_RETRY_INTERVAL - private val badCertTargets = mutableSetOf() + private val handshakeFailureRetryTargets = mutableSetOf() + private var retryingHandshakeFailures = false + private var retryOffset = 0 @Volatile private var amqpActive = false @Volatile @@ -91,22 +95,67 @@ class AMQPClient(val targets: List, val localAddressString: String get() = clientChannel?.localAddress()?.toString() ?: "" - private fun nextTarget() { + /* + Figure out the index of the next address to try to connect to + */ + private fun setTargetIndex() { val origIndex = targetIndex targetIndex = -1 for (offset in 1..targets.size) { val newTargetIndex = (origIndex + offset).rem(targets.size) - if (targets[newTargetIndex] !in badCertTargets) { + if (targets[newTargetIndex] !in handshakeFailureRetryTargets ) { targetIndex = newTargetIndex break } } - if (targetIndex == -1) { - log.error("No targets have presented acceptable certificates for $allowedRemoteLegalNames. Halting retries") - return + } + + /* + Set how long to wait until trying to connect to the next address + */ + private fun setTargetRetryInterval() { + retryInterval = if (retryingHandshakeFailures) { + if (retryOffset < handshakeRetryIntervals.size) { + handshakeRetryIntervals[retryOffset++].toMillis() + } else { + Duration.ofDays(1).toMillis() + } + } else { + min(MAX_RETRY_INTERVAL, retryInterval * BACKOFF_MULTIPLIER) } - log.info("Retry connect to ${targets[targetIndex]}") - retryInterval = min(MAX_RETRY_INTERVAL, retryInterval * BACKOFF_MULTIPLIER) + } + + /* + Once a connection is made, reset all the retry-connection info so if there is another connection failure + then this node tries to reconnect quickly. + */ + private fun successfullyConnected() { + log.info("Successfully connected to [${targets[targetIndex]}]; resetting the target connection-retry interval") + retryingHandshakeFailures = false + retryInterval = MIN_RETRY_INTERVAL + retryOffset = 0 + } + + /* + Set the next target to connect to + */ + private fun nextTarget() { + setTargetIndex() + + if (targetIndex == -1) { + if (handshakeFailureRetryTargets.isNotEmpty()) { + log.info("Failed to connect to any targets. Retrying targets that previously failed to handshake.") + handshakeFailureRetryTargets.clear() + retryingHandshakeFailures = true + setTargetIndex() + } else { + log.error("Attempted connection to targets: $targets, but none of them have presented acceptable certificates" + + " for $allowedRemoteLegalNames. Halting retries.") + return + } + } + setTargetRetryInterval() + log.info("Retry connect to ${targets[targetIndex]} in [$retryInterval] ms") } private val connectListener = object : ChannelFutureListener { @@ -212,7 +261,7 @@ class AMQPClient(val targets: List, onOpen = { _, change -> parent.run { amqpActive = true - retryInterval = MIN_RETRY_INTERVAL // reset to fast reconnect if we connect properly + successfullyConnected() _onConnection.onNext(change) } }, @@ -220,9 +269,9 @@ class AMQPClient(val targets: List, if (parent.amqpChannelHandler == amqpChannelHandler) { parent.run { _onConnection.onNext(change) - if (change.badCert) { - log.error("Blocking future connection attempts to $target due to bad certificate on endpoint") - badCertTargets += target + if (change.connectionResult == ConnectionResult.HANDSHAKE_FAILURE) { + log.warn("Handshake failure with $target target; will retry later") + handshakeFailureRetryTargets += target } if (started && amqpActive) { diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/ConnectionChange.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/ConnectionChange.kt index da839954ce..e900f93306 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/ConnectionChange.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/ConnectionChange.kt @@ -3,8 +3,8 @@ package net.corda.nodeapi.internal.protonwrapper.netty import java.net.InetSocketAddress import java.security.cert.X509Certificate -data class ConnectionChange(val remoteAddress: InetSocketAddress, val remoteCert: X509Certificate?, val connected: Boolean, val badCert: Boolean) { +data class ConnectionChange(val remoteAddress: InetSocketAddress, val remoteCert: X509Certificate?, val connected: Boolean, val connectionResult: ConnectionResult) { override fun toString(): String { - return "ConnectionChange remoteAddress: $remoteAddress connected state: $connected cert subject: ${remoteCert?.subjectDN} cert ok: ${!badCert}" + return "ConnectionChange remoteAddress: $remoteAddress connected state: $connected cert subject: ${remoteCert?.subjectDN} result: ${connectionResult}" } -} \ No newline at end of file +} diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/ConnectionResult.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/ConnectionResult.kt new file mode 100644 index 0000000000..fbd67bc138 --- /dev/null +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/ConnectionResult.kt @@ -0,0 +1,6 @@ +package net.corda.nodeapi.internal.protonwrapper.netty + +enum class ConnectionResult { + NO_ERROR, + HANDSHAKE_FAILURE +} diff --git a/node/src/integration-test/kotlin/net/corda/node/amqp/AMQPClientSslErrorsTest.kt b/node/src/integration-test/kotlin/net/corda/node/amqp/AMQPClientSslErrorsTest.kt index b1bf4b99f8..dd85bae8e7 100644 --- a/node/src/integration-test/kotlin/net/corda/node/amqp/AMQPClientSslErrorsTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/amqp/AMQPClientSslErrorsTest.kt @@ -14,6 +14,7 @@ import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.configureWithDevSSLCertificate import net.corda.nodeapi.internal.protonwrapper.netty.AMQPClient import net.corda.nodeapi.internal.protonwrapper.netty.AMQPConfiguration +import net.corda.nodeapi.internal.protonwrapper.netty.ConnectionResult import net.corda.nodeapi.internal.protonwrapper.netty.init import net.corda.nodeapi.internal.protonwrapper.netty.initialiseTrustStoreAndEnableCrlChecking import net.corda.nodeapi.internal.protonwrapper.netty.toRevocationConfig @@ -29,6 +30,7 @@ import org.junit.runner.RunWith import org.junit.runners.Parameterized import javax.net.ssl.KeyManagerFactory import javax.net.ssl.TrustManagerFactory +import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -211,7 +213,7 @@ class AMQPClientSslErrorsTest(@Suppress("unused") private val iteration: Int) { val clientConnect = clientConnected.get() assertFalse(clientConnect.connected) // Not a badCert, but a timeout during handshake - assertFalse(clientConnect.badCert) + assertEquals(ConnectionResult.NO_ERROR, clientConnect.connectionResult) } } assertFalse(serverThread.isActive) diff --git a/node/src/integration-test/kotlin/net/corda/node/amqp/ProtonWrapperTests.kt b/node/src/integration-test/kotlin/net/corda/node/amqp/ProtonWrapperTests.kt index 3f0ac98f4c..b067f24b40 100644 --- a/node/src/integration-test/kotlin/net/corda/node/amqp/ProtonWrapperTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/amqp/ProtonWrapperTests.kt @@ -36,6 +36,7 @@ import net.corda.coretesting.internal.stubs.CertificateStoreStubs import net.corda.nodeapi.internal.protonwrapper.netty.toRevocationConfig import org.apache.activemq.artemis.api.core.QueueConfiguration import org.apache.activemq.artemis.api.core.RoutingType +import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.Assert.assertArrayEquals import org.junit.Rule @@ -207,6 +208,103 @@ class ProtonWrapperTests { assertTrue(done) } + @Suppress("TooGenericExceptionCaught") // Too generic exception thrown! + @Test(timeout=300_000) + fun `AMPQClient that fails to handshake with a server will retry the server`() { + /* + This test has been modelled on `Test AMQP Client with invalid root certificate`, above. + The aim is to set up a server with an invalid root cert so that the TLS handshake will fail. + The test allows the AMQPClient to retry the connection (which it should do). + */ + + val certificatesDirectory = temporaryFolder.root.toPath() + val signingCertificateStore = CertificateStoreStubs.Signing.withCertificatesDirectory(certificatesDirectory, "serverstorepass") + val sslConfig = CertificateStoreStubs.P2P.withCertificatesDirectory(certificatesDirectory, keyStorePassword = "serverstorepass") + + val (rootCa, intermediateCa) = createDevIntermediateCaCertPath() + + // Generate server cert and private key and populate another keystore suitable for SSL + signingCertificateStore.get(true).also { it.installDevNodeCaCertPath(ALICE_NAME, rootCa.certificate, intermediateCa) } + sslConfig.keyStore.get(true).also { it.registerDevP2pCertificates(ALICE_NAME, rootCa.certificate, intermediateCa) } + sslConfig.createTrustStore(rootCa.certificate) + + val keyStore = sslConfig.keyStore.get() + val trustStore = sslConfig.trustStore.get() + + val context = SSLContext.getInstance("TLS") + val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) + keyManagerFactory.init(keyStore) + val keyManagers = keyManagerFactory.keyManagers + val trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) + trustMgrFactory.init(trustStore) + val trustManagers = trustMgrFactory.trustManagers + context.init(keyManagers, trustManagers, newSecureRandom()) + + val serverSocketFactory = context.serverSocketFactory + + val serverSocket = serverSocketFactory.createServerSocket(serverPort) as SSLServerSocket + val serverParams = SSLParameters(ArtemisTcpTransport.CIPHER_SUITES.toTypedArray(), + arrayOf("TLSv1.2")) + serverParams.wantClientAuth = true + serverParams.needClientAuth = true + serverParams.endpointIdentificationAlgorithm = null // Reconfirm default no server name indication, use our own validator. + serverSocket.sslParameters = serverParams + serverSocket.useClientMode = false + + var done = false + var handshakeErrorCount = 0 + + // + // This is the thread that acts as the server-side endpoint for the AMQPClient to connect to. + // + val serverThread = thread { + // + // The server thread will keep making itself available for SSL connections until + // the 'done' flag is set by the client thread, later on. + // + while (!done) { + try { + val sslServerSocket = serverSocket.accept() as SSLSocket + sslServerSocket.addHandshakeCompletedListener { + done = true + } + sslServerSocket.startHandshake() + } catch (ex: SSLException) { + ++handshakeErrorCount + } catch (e: Throwable) { + println(e) + } + } + } + + // + // Create the AMQPClient but only specify one server endpoint to connect to. + // + val amqpClient = createClient(serverAddressList = listOf(NetworkHostAndPort("localhost", serverPort))) + amqpClient.use { + + amqpClient.start() + // + // Waiting for the number of handshake errors to get to at least 2. + // This happens when the AMQPClient has made it's first retry attempt, which is + // what this test is interested in. + // + while (handshakeErrorCount < 2) { + Thread.sleep(2) + } + done = true + } + + serverThread.join(1000) + // + // check that there was at least one retry i.e. > 1 handshake error. + // + Assertions.assertThat(handshakeErrorCount > 1).isTrue() + + serverSocket.close() + assertTrue(done) + } + @Test(timeout=300_000) fun `Client Failover for multiple IP`() { @@ -450,7 +548,11 @@ class ProtonWrapperTests { return Pair(server, client) } - private fun createClient(maxMessageSize: Int = MAX_MESSAGE_SIZE): AMQPClient { + private fun createClient(maxMessageSize: Int = MAX_MESSAGE_SIZE, + serverAddressList: List = listOf( + NetworkHostAndPort("localhost", serverPort), + NetworkHostAndPort("localhost", serverPort2), + NetworkHostAndPort("localhost", artemisPort))): AMQPClient { val baseDirectory = temporaryFolder.root.toPath() / "client" val certificatesDirectory = baseDirectory / "certificates" val signingCertificateStore = CertificateStoreStubs.Signing.withCertificatesDirectory(certificatesDirectory) @@ -474,9 +576,7 @@ class ProtonWrapperTests { override val maxMessageSize: Int = maxMessageSize } return AMQPClient( - listOf(NetworkHostAndPort("localhost", serverPort), - NetworkHostAndPort("localhost", serverPort2), - NetworkHostAndPort("localhost", artemisPort)), + serverAddressList, setOf(ALICE_NAME, CHARLIE_NAME), amqpConfig) } From 0ab4ac94c880aa98033cf618e82be7a8c54dcc6c Mon Sep 17 00:00:00 2001 From: Chris Cochrane <78791827+chriscochrane@users.noreply.github.com> Date: Fri, 30 Sep 2022 17:49:21 +0100 Subject: [PATCH 50/93] ENT-6903 - address security issues reported by Snyk (#7244) ENT-6903: Update versions of BC, Shiro, Netty okhttp Also updated platform version to 12. --- build.gradle | 1 - constants.properties | 12 ++++++------ .../kotlin/net/corda/core/internal/CordaUtils.kt | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index 262c0320b7..1461a6d005 100644 --- a/build.gradle +++ b/build.gradle @@ -106,7 +106,6 @@ buildscript { ext.hikari_version = constants.getProperty("hikariVersion") ext.liquibase_version = constants.getProperty("liquibaseVersion") ext.artifactory_contextUrl = 'https://software.r3.com/artifactory' - ext.snake_yaml_version = constants.getProperty('snakeYamlVersion') ext.docker_compose_rule_version = constants.getProperty("dockerComposeRuleVersion") ext.selenium_version = constants.getProperty("seleniumVersion") ext.ghostdriver_version = constants.getProperty("ghostdriverVersion") diff --git a/constants.properties b/constants.properties index 3f63879556..7abfbb8df0 100644 --- a/constants.properties +++ b/constants.properties @@ -12,7 +12,7 @@ java8MinUpdateVersion=171 # When incrementing platformVersion make sure to update # # net.corda.core.internal.CordaUtilsKt.PLATFORM_VERSION as well. # # ***************************************************************# -platformVersion=11 +platformVersion=12 guavaVersion=28.0-jre # Quasar version to use with Java 8: quasarVersion=0.7.15_r3 @@ -21,13 +21,13 @@ quasarVersion11=0.8.1_r3 jdkClassifier11=jdk11 dockerJavaVersion=3.2.5 proguardVersion=6.1.1 -bouncycastleVersion=1.68 +// bouncy castle version must not be changed on a patch release. Needs a full release test cycle to flush out any issues. +bouncycastleVersion=1.69 classgraphVersion=4.8.135 disruptorVersion=3.4.2 typesafeConfigVersion=1.3.4 jsr305Version=3.0.2 artifactoryPluginVersion=4.16.1 -snakeYamlVersion=1.19 caffeineVersion=2.9.3 metricsVersion=4.1.0 metricsNewRelicVersion=1.1.1 @@ -56,8 +56,8 @@ servletVersion=4.0.1 assertjVersion=3.12.2 slf4JVersion=1.7.30 log4JVersion=2.17.1 -okhttpVersion=3.14.2 -nettyVersion=4.1.77.Final +okhttpVersion=3.14.9 +nettyVersion=4.1.82.Final fileuploadVersion=1.4 kryoVersion=4.0.2 kryoSerializerVersion=0.43 @@ -83,7 +83,7 @@ eddsaVersion=0.3.0 dependencyCheckerVersion=5.2.0 commonsCollectionsVersion=4.3 beanutilsVersion=1.9.4 -shiroVersion=1.8.0 +shiroVersion=1.9.1 hikariVersion=3.3.1 liquibaseVersion=3.6.3 dockerComposeRuleVersion=1.5.0 diff --git a/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt b/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt index 3e09be0ff4..72608450cb 100644 --- a/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt +++ b/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt @@ -30,7 +30,7 @@ import java.util.jar.JarInputStream // When incrementing platformVersion make sure to update PLATFORM_VERSION in constants.properties as well. -const val PLATFORM_VERSION = 11 +const val PLATFORM_VERSION = 12 fun ServicesForResolution.ensureMinimumPlatformVersion(requiredMinPlatformVersion: Int, feature: String) { checkMinimumPlatformVersion(networkParameters.minimumPlatformVersion, requiredMinPlatformVersion, feature) From 1ec93f01e176000b51ca5e80b8d410b2e7daf25d Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Thu, 6 Oct 2022 12:33:36 +0100 Subject: [PATCH 51/93] Reverted netty back to 4.1.77.Final --- constants.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constants.properties b/constants.properties index 7abfbb8df0..bfc3044c0d 100644 --- a/constants.properties +++ b/constants.properties @@ -57,7 +57,7 @@ assertjVersion=3.12.2 slf4JVersion=1.7.30 log4JVersion=2.17.1 okhttpVersion=3.14.9 -nettyVersion=4.1.82.Final +nettyVersion=4.1.77.Final fileuploadVersion=1.4 kryoVersion=4.0.2 kryoSerializerVersion=0.43 From c23f74bc3fbaf10aefff2c1e5193aabf42b1fe83 Mon Sep 17 00:00:00 2001 From: Adel El-Beik Date: Fri, 14 Oct 2022 12:09:34 +0100 Subject: [PATCH 52/93] ENT-6975: Updated docker jdk version to 345 for zulu ubuntu and 8u342-al2 for amazon corretto. --- docker/src/docker/Dockerfile | 2 +- docker/src/docker/Dockerfile-debug | 2 +- docker/src/docker/DockerfileAL | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/src/docker/Dockerfile b/docker/src/docker/Dockerfile index b87898e1d2..ecef09e974 100644 --- a/docker/src/docker/Dockerfile +++ b/docker/src/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM azul/zulu-openjdk:8u322 +FROM azul/zulu-openjdk:8u345 ## Add packages, clean cache, create dirs, create corda user and change ownership RUN apt-get update && \ diff --git a/docker/src/docker/Dockerfile-debug b/docker/src/docker/Dockerfile-debug index 6f69c0b2d5..e84148ae3e 100644 --- a/docker/src/docker/Dockerfile-debug +++ b/docker/src/docker/Dockerfile-debug @@ -1,4 +1,4 @@ -FROM azul/zulu-openjdk:8u322 +FROM azul/zulu-openjdk:8u345 ## Add packages, clean cache, create dirs, create corda user and change ownership RUN apt-get update && \ diff --git a/docker/src/docker/DockerfileAL b/docker/src/docker/DockerfileAL index eee206714b..cc6b505120 100644 --- a/docker/src/docker/DockerfileAL +++ b/docker/src/docker/DockerfileAL @@ -1,4 +1,4 @@ -FROM amazoncorretto:8u322-al2 +FROM amazoncorretto:8u342-al2 ## Add packages, clean cache, create dirs, create corda user and change ownership RUN yum -y install bash && \ From 64d31d3fb39f0de62665d4745e4c3eb1258c02d4 Mon Sep 17 00:00:00 2001 From: Chris Cochrane Date: Mon, 17 Oct 2022 17:44:32 +0100 Subject: [PATCH 53/93] Upgraded shiro and apache commons-text, to address security issues. --- build.gradle | 9 +++++++-- constants.properties | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 1461a6d005..1ad956bd92 100644 --- a/build.gradle +++ b/build.gradle @@ -122,6 +122,7 @@ buildscript { ext.detekt_version = constants.getProperty('detektVersion') ext.docker_java_version = constants.getProperty("dockerJavaVersion") ext.commons_configuration2_version = constants.getProperty("commonsConfiguration2Version") + ext.commons_text_version = constants.getProperty("commonsTextVersion") if (JavaVersion.current().isJava8()) { ext.fontawesomefx_commons_version = constants.getProperty("fontawesomefxCommonsJava8Version") ext.fontawesomefx_fontawesome_version = constants.getProperty("fontawesomefxFontawesomeJava8Version") @@ -455,8 +456,12 @@ allprojects { } } - if (details.requested.group == 'org.apache.commons' && details.requested.name == "commons-configuration2") { - details.useVersion commons_configuration2_version + if (details.requested.group == 'org.apache.commons') { + if (details.requested.name == "commons-configuration2") { + details.useVersion commons_configuration2_version + } else if (details.requested.name == "commons-text") { + details.useVersion commons_text_version + } } } diff --git a/constants.properties b/constants.properties index bfc3044c0d..eee0ada384 100644 --- a/constants.properties +++ b/constants.properties @@ -39,6 +39,7 @@ jolokiaAgentVersion=1.6.1 detektVersion=1.0.1 tcnativeVersion=2.0.48.Final commonsConfiguration2Version=2.8.0 +commonsTextVersion=1.10.0 # ENT-6607 all third party version in here now @@ -83,7 +84,7 @@ eddsaVersion=0.3.0 dependencyCheckerVersion=5.2.0 commonsCollectionsVersion=4.3 beanutilsVersion=1.9.4 -shiroVersion=1.9.1 +shiroVersion=1.10.0 hikariVersion=3.3.1 liquibaseVersion=3.6.3 dockerComposeRuleVersion=1.5.0 From b29713d7b9be1bad3a4994770981e8b477d73217 Mon Sep 17 00:00:00 2001 From: Rick Parker Date: Tue, 18 Oct 2022 09:28:41 +0100 Subject: [PATCH 54/93] ENT-6947 Intern common types to reduce heap footprint (#7239) ENT-6947: Implement interning for SecureHash, CordaX500Name, PublicKey, AsbtractParty and SignatureAttachmentConstraint, including automatic detection of internable types off companion objects in AMQP & Kyro deserialization. In some cases, add new factory methods to companion objects, and make main code base use them. Performance tested in performance cluster with no negative impact visible (so default concurrency setting seems okay). Testing suggests 5-6x memory saving for tokens in TokensSDK in memory selector. Should see approx. 1 million tokens per GB or better (1.5 million for the tokens we tested with). --- .ci/api-current.txt | 289 +++++++++++++++++- .idea/codeStyles/Project.xml | 5 +- .idea/codeStyles/codeStyleConfig.xml | 1 - .../kotlin/rpc/StandaloneCordaRPClientTest.kt | 4 +- .../net/corda/common/logging/Constants.kt | 2 +- core-deterministic/build.gradle | 2 + .../internal/utilities/PrivateInterner.kt | 16 + core/build.gradle | 2 +- .../core/contracts/AttachmentConstraint.kt | 16 +- .../corda/core/crypto/CompositeSignature.kt | 10 +- .../kotlin/net/corda/core/crypto/Crypto.kt | 31 +- .../net/corda/core/crypto/SecureHash.kt | 42 ++- .../net/corda/core/identity/AbstractParty.kt | 15 + .../net/corda/core/identity/AnonymousParty.kt | 7 + .../net/corda/core/identity/CordaX500Name.kt | 10 +- .../kotlin/net/corda/core/identity/Party.kt | 12 + .../core/identity/PartyAndCertificate.kt | 8 +- .../net/corda/core/internal/InternalUtils.kt | 3 +- .../core/internal/utilities/Internable.kt | 24 ++ .../internal/utilities/PrivateInterner.kt | 69 +++++ .../corda/core/node/services/VaultService.kt | 2 +- .../internal/AttachmentsClassLoader.kt | 5 +- .../core/transactions/TransactionBuilder.kt | 3 +- .../serialization/kryo/CordaClassResolver.kt | 31 +- .../kryo/DefaultKryoCustomizer.kt | 7 +- .../internal/serialization/kryo/KryoTests.kt | 63 +++- .../persistence/NodeAttachmentService.kt | 33 +- .../internal/SecureHashSerializationTest.kt | 3 + .../internal/amqp/InterningSerializer.kt | 24 ++ .../internal/amqp/ObjectSerializer.kt | 6 +- .../internal/amqp/RoundTripTests.kt | 44 ++- 31 files changed, 707 insertions(+), 82 deletions(-) create mode 100644 core-deterministic/src/main/kotlin/net/corda/core/internal/utilities/PrivateInterner.kt create mode 100644 core/src/main/kotlin/net/corda/core/internal/utilities/Internable.kt create mode 100644 core/src/main/kotlin/net/corda/core/internal/utilities/PrivateInterner.kt create mode 100644 serialization/src/main/kotlin/net/corda/serialization/internal/amqp/InterningSerializer.kt diff --git a/.ci/api-current.txt b/.ci/api-current.txt index 39388ad791..f189b97fea 100644 --- a/.ci/api-current.txt +++ b/.ci/api-current.txt @@ -804,7 +804,16 @@ public final class net.corda.core.contracts.PartyAndReference extends java.lang. @CordaSerializable public final class net.corda.core.contracts.PrivacySalt extends net.corda.core.utilities.OpaqueBytes public () + public (int) public (byte[]) + @NotNull + public static final net.corda.core.contracts.PrivacySalt createFor(String) + public static final net.corda.core.contracts.PrivacySalt$Companion Companion +## +public static final class net.corda.core.contracts.PrivacySalt$Companion extends java.lang.Object + public (kotlin.jvm.internal.DefaultConstructorMarker) + @NotNull + public final net.corda.core.contracts.PrivacySalt createFor(String) ## public final class net.corda.core.contracts.ReferencedStateAndRef extends java.lang.Object public (net.corda.core.contracts.StateAndRef) @@ -882,6 +891,14 @@ public final class net.corda.core.contracts.SignatureAttachmentConstraint extend public boolean isSatisfiedBy(net.corda.core.contracts.Attachment) @NotNull public String toString() + public static final net.corda.core.contracts.SignatureAttachmentConstraint$Companion Companion +## +public static final class net.corda.core.contracts.SignatureAttachmentConstraint$Companion extends java.lang.Object implements net.corda.core.internal.utilities.Internable + public (kotlin.jvm.internal.DefaultConstructorMarker) + @NotNull + public final net.corda.core.contracts.SignatureAttachmentConstraint create(java.security.PublicKey) + @NotNull + public net.corda.core.internal.utilities.PrivateInterner getInterner() ## public final class net.corda.core.contracts.SourceAndAmount extends java.lang.Object public (P, net.corda.core.contracts.Amount, Object) @@ -999,6 +1016,8 @@ public final class net.corda.core.contracts.Structures extends java.lang.Object @NotNull public static final net.corda.core.crypto.SecureHash hash(net.corda.core.contracts.ContractState) @NotNull + public static final net.corda.core.crypto.SecureHash hash(net.corda.core.contracts.ContractState, String) + @NotNull public static final net.corda.core.contracts.Amount withoutIssuer(net.corda.core.contracts.Amount>) public static final int MAX_ISSUER_REF_SIZE = 512 ## @@ -1099,6 +1118,10 @@ public abstract class net.corda.core.contracts.TransactionVerificationException public final net.corda.core.crypto.SecureHash getTxId() ## @CordaSerializable +public static final class net.corda.core.contracts.TransactionVerificationException$AttachmentTooBigException extends net.corda.core.contracts.TransactionVerificationException + public (net.corda.core.crypto.SecureHash) +## +@CordaSerializable public static final class net.corda.core.contracts.TransactionVerificationException$BrokenTransactionException extends net.corda.core.contracts.TransactionVerificationException public (net.corda.core.crypto.SecureHash, String) ## @@ -1257,6 +1280,10 @@ public static final class net.corda.core.contracts.TransactionVerificationExcept public (net.corda.core.crypto.SecureHash, String, Throwable) ## @CordaSerializable +public static final class net.corda.core.contracts.TransactionVerificationException$UnsupportedHashTypeException extends net.corda.core.contracts.TransactionVerificationException + public (net.corda.core.crypto.SecureHash) +## +@CordaSerializable public static final class net.corda.core.contracts.TransactionVerificationException$UntrustedAttachmentsException extends net.corda.core.CordaException public (net.corda.core.crypto.SecureHash, java.util.List) @NotNull @@ -1861,6 +1888,53 @@ public interface net.corda.core.crypto.DigestAlgorithm public abstract byte[] nonceDigest(byte[]) ## @CordaSerializable +public final class net.corda.core.crypto.DigestService extends java.lang.Object + public (String) + @NotNull + public final String component1() + @NotNull + public final net.corda.core.crypto.SecureHash componentHash(net.corda.core.crypto.SecureHash, net.corda.core.utilities.OpaqueBytes) + @NotNull + public final net.corda.core.crypto.SecureHash componentHash(net.corda.core.utilities.OpaqueBytes, net.corda.core.contracts.PrivacySalt, int, int) + @NotNull + public final net.corda.core.crypto.SecureHash computeNonce(net.corda.core.contracts.PrivacySalt, int, int) + @NotNull + public final net.corda.core.crypto.DigestService copy(String) + public boolean equals(Object) + @NotNull + public final net.corda.core.crypto.SecureHash getAllOnesHash() + public final int getDigestLength() + @NotNull + public final String getHashAlgorithm() + @NotNull + public final net.corda.core.crypto.SecureHash getZeroHash() + @NotNull + public final net.corda.core.crypto.SecureHash hash(String) + @NotNull + public final net.corda.core.crypto.SecureHash hash(byte[]) + public int hashCode() + @NotNull + public final net.corda.core.crypto.SecureHash serializedHash(T) + @NotNull + public String toString() + public static final net.corda.core.crypto.DigestService$Companion Companion +## +public static final class net.corda.core.crypto.DigestService$Companion extends java.lang.Object + public (kotlin.jvm.internal.DefaultConstructorMarker) + @NotNull + public final net.corda.core.crypto.DigestService getDefault() + @NotNull + public final net.corda.core.crypto.DigestService getSha2_256() + @NotNull + public final net.corda.core.crypto.DigestService getSha2_384() + @NotNull + public final net.corda.core.crypto.DigestService getSha2_512() +## +public final class net.corda.core.crypto.DigestServiceKt extends java.lang.Object + @NotNull + public static final net.corda.core.crypto.SecureHash randomHash(net.corda.core.crypto.DigestService) +## +@CordaSerializable public class net.corda.core.crypto.DigitalSignature extends net.corda.core.utilities.OpaqueBytes public (byte[]) ## @@ -1888,6 +1962,8 @@ public static final class net.corda.core.crypto.MerkleTree$Companion extends jav public (kotlin.jvm.internal.DefaultConstructorMarker) @NotNull public final net.corda.core.crypto.MerkleTree getMerkleTree(java.util.List) + @NotNull + public final net.corda.core.crypto.MerkleTree getMerkleTree(java.util.List, net.corda.core.crypto.DigestService) ## public static final class net.corda.core.crypto.MerkleTree$Leaf extends net.corda.core.crypto.MerkleTree public (net.corda.core.crypto.SecureHash) @@ -1997,14 +2073,23 @@ public static final class net.corda.core.crypto.PartialMerkleTree$PartialTree$Le ## @CordaSerializable public static final class net.corda.core.crypto.PartialMerkleTree$PartialTree$Node extends net.corda.core.crypto.PartialMerkleTree$PartialTree + @DeprecatedConstructorForDeserialization public (net.corda.core.crypto.PartialMerkleTree$PartialTree, net.corda.core.crypto.PartialMerkleTree$PartialTree) + public (net.corda.core.crypto.PartialMerkleTree$PartialTree, net.corda.core.crypto.PartialMerkleTree$PartialTree, String) + public (net.corda.core.crypto.PartialMerkleTree$PartialTree, net.corda.core.crypto.PartialMerkleTree$PartialTree, String, int, kotlin.jvm.internal.DefaultConstructorMarker) @NotNull public final net.corda.core.crypto.PartialMerkleTree$PartialTree component1() @NotNull public final net.corda.core.crypto.PartialMerkleTree$PartialTree component2() + @Nullable + public final String component3() @NotNull public final net.corda.core.crypto.PartialMerkleTree$PartialTree$Node copy(net.corda.core.crypto.PartialMerkleTree$PartialTree, net.corda.core.crypto.PartialMerkleTree$PartialTree) + @NotNull + public final net.corda.core.crypto.PartialMerkleTree$PartialTree$Node copy(net.corda.core.crypto.PartialMerkleTree$PartialTree, net.corda.core.crypto.PartialMerkleTree$PartialTree, String) public boolean equals(Object) + @Nullable + public final String getHashAlgorithm() @NotNull public final net.corda.core.crypto.PartialMerkleTree$PartialTree getLeft() @NotNull @@ -2017,36 +2102,86 @@ public static final class net.corda.core.crypto.PartialMerkleTree$PartialTree$No public abstract class net.corda.core.crypto.SecureHash extends net.corda.core.utilities.OpaqueBytes public (byte[], kotlin.jvm.internal.DefaultConstructorMarker) @NotNull + public static final net.corda.core.crypto.SecureHash allOnesHashFor(String) + @NotNull + public static final net.corda.core.crypto.SecureHash componentHashAs(String, byte[]) + @NotNull + public final net.corda.core.crypto.SecureHash concatenate(net.corda.core.crypto.SecureHash) + @NotNull + public final net.corda.core.crypto.SecureHash concatenateAs(String, net.corda.core.crypto.SecureHash) + @NotNull + public static final net.corda.core.crypto.SecureHash create(String) + @NotNull + public static final net.corda.core.crypto.SecureHash$SHA256 createSHA256(byte[]) + @NotNull + protected net.corda.core.crypto.SecureHash generate(byte[]) + @NotNull + public static final net.corda.core.crypto.SecureHash hashAs(String, byte[]) + @NotNull public final net.corda.core.crypto.SecureHash$SHA256 hashConcat(net.corda.core.crypto.SecureHash) @NotNull + public static final net.corda.core.crypto.SecureHash nonceHashAs(String, byte[]) + @NotNull public static final net.corda.core.crypto.SecureHash$SHA256 parse(String) @NotNull public final String prefixChars(int) @NotNull + public static final net.corda.core.crypto.SecureHash random(String) + @NotNull public static final net.corda.core.crypto.SecureHash$SHA256 randomSHA256() @NotNull + public final net.corda.core.crypto.SecureHash reHash() + @NotNull public static final net.corda.core.crypto.SecureHash$SHA256 sha256(String) @NotNull public static final net.corda.core.crypto.SecureHash$SHA256 sha256(byte[]) @NotNull public static final net.corda.core.crypto.SecureHash$SHA256 sha256Twice(byte[]) @NotNull + public final String toHexString() + @NotNull public String toString() + @NotNull + public static final net.corda.core.crypto.SecureHash zeroHashFor(String) public static final net.corda.core.crypto.SecureHash$Companion Companion + public static final char DELIMITER = ':' + @NotNull + public static final String SHA2_256 = "SHA-256" + @NotNull + public static final String SHA2_384 = "SHA-384" + @NotNull + public static final String SHA2_512 = "SHA-512" @NotNull public static final net.corda.core.crypto.SecureHash$SHA256 allOnesHash @NotNull public static final net.corda.core.crypto.SecureHash$SHA256 zeroHash ## -public static final class net.corda.core.crypto.SecureHash$Companion extends java.lang.Object +public static final class net.corda.core.crypto.SecureHash$Companion extends java.lang.Object implements net.corda.core.internal.utilities.Internable public (kotlin.jvm.internal.DefaultConstructorMarker) @NotNull + public final net.corda.core.crypto.SecureHash allOnesHashFor(String) + @NotNull + public final net.corda.core.crypto.SecureHash componentHashAs(String, byte[]) + @NotNull + public final net.corda.core.crypto.SecureHash create(String) + @NotNull + public final net.corda.core.crypto.SecureHash$SHA256 createSHA256(byte[]) + public final int digestLengthFor(String) + @NotNull public final net.corda.core.crypto.SecureHash$SHA256 getAllOnesHash() @NotNull + public net.corda.core.internal.utilities.PrivateInterner getInterner() + @NotNull public final net.corda.core.crypto.SecureHash$SHA256 getZeroHash() @NotNull + public final net.corda.core.crypto.SecureHash hashAs(String, byte[]) + @NotNull + public final net.corda.core.crypto.SecureHash nonceHashAs(String, byte[]) + @NotNull public final net.corda.core.crypto.SecureHash$SHA256 parse(String) @NotNull + public final net.corda.core.crypto.SecureHash random(String) + @NotNull public final net.corda.core.crypto.SecureHash$SHA256 randomSHA256() @NotNull public final net.corda.core.crypto.SecureHash$SHA256 sha256(String) @@ -2054,14 +2189,39 @@ public static final class net.corda.core.crypto.SecureHash$Companion extends jav public final net.corda.core.crypto.SecureHash$SHA256 sha256(byte[]) @NotNull public final net.corda.core.crypto.SecureHash$SHA256 sha256Twice(byte[]) + @NotNull + public final net.corda.core.crypto.SecureHash zeroHashFor(String) +## +@CordaSerializable +public static final class net.corda.core.crypto.SecureHash$HASH extends net.corda.core.crypto.SecureHash + public (String, byte[]) + public boolean equals(Object) + @NotNull + protected net.corda.core.crypto.SecureHash generate(byte[]) + @NotNull + public final String getAlgorithm() + public int hashCode() + @NotNull + public String toString() ## @CordaSerializable public static final class net.corda.core.crypto.SecureHash$SHA256 extends net.corda.core.crypto.SecureHash public (byte[]) public boolean equals(Object) + @NotNull + protected net.corda.core.crypto.SecureHash generate(byte[]) public int hashCode() + @NotNull + public String toString() ## public final class net.corda.core.crypto.SecureHashKt extends java.lang.Object + @NotNull + public static final String getAlgorithm(net.corda.core.crypto.SecureHash) + @NotNull + public static final net.corda.core.crypto.SecureHash hashAs(net.corda.core.utilities.OpaqueBytes, String) + @NotNull + public static final net.corda.core.crypto.SecureHash hashAs(byte[], String) + public static final boolean isZero(net.corda.core.utilities.OpaqueBytes) @NotNull public static final net.corda.core.crypto.SecureHash$SHA256 sha256(net.corda.core.utilities.OpaqueBytes) @NotNull @@ -3157,6 +3317,24 @@ public static final class net.corda.core.flows.WithReferencedStatesFlow$Companio public static final class net.corda.core.flows.WithReferencedStatesFlow$Companion$SUCCESS extends net.corda.core.utilities.ProgressTracker$Step public static final net.corda.core.flows.WithReferencedStatesFlow$Companion$SUCCESS INSTANCE ## +@CordaSerializable +public final class net.corda.core.flows.WrappedFlowExternalAsyncOperation extends java.lang.Object implements net.corda.core.internal.FlowAsyncOperation + public (net.corda.core.flows.FlowExternalAsyncOperation) + @NotNull + public net.corda.core.concurrent.CordaFuture execute(String) + @NotNull + public final net.corda.core.flows.FlowExternalAsyncOperation getOperation() +## +@CordaSerializable +public final class net.corda.core.flows.WrappedFlowExternalOperation extends java.lang.Object implements net.corda.core.internal.FlowAsyncOperation + public (net.corda.core.internal.ServiceHubCoreInternal, net.corda.core.flows.FlowExternalOperation) + @NotNull + public net.corda.core.concurrent.CordaFuture execute(String) + @NotNull + public final net.corda.core.flows.FlowExternalOperation getOperation() + @NotNull + public final net.corda.core.internal.ServiceHubCoreInternal getServiceHub() +## @DoNotImplement @CordaSerializable public abstract class net.corda.core.identity.AbstractParty extends java.lang.Object implements net.corda.core.flows.Destination @@ -3171,6 +3349,7 @@ public abstract class net.corda.core.identity.AbstractParty extends java.lang.Ob public abstract net.corda.core.contracts.PartyAndReference ref(net.corda.core.utilities.OpaqueBytes) @NotNull public final net.corda.core.contracts.PartyAndReference ref(byte...) + public static final net.corda.core.identity.AbstractParty$Companion Companion ## @DoNotImplement @CordaSerializable @@ -3182,6 +3361,12 @@ public final class net.corda.core.identity.AnonymousParty extends net.corda.core public net.corda.core.contracts.PartyAndReference ref(net.corda.core.utilities.OpaqueBytes) @NotNull public String toString() + public static final net.corda.core.identity.AnonymousParty$Companion Companion +## +public static final class net.corda.core.identity.AnonymousParty$Companion extends java.lang.Object + public (kotlin.jvm.internal.DefaultConstructorMarker) + @NotNull + public final net.corda.core.identity.AnonymousParty create(java.security.PublicKey) ## @CordaSerializable public final class net.corda.core.identity.CordaX500Name extends java.lang.Object @@ -3232,11 +3417,13 @@ public final class net.corda.core.identity.CordaX500Name extends java.lang.Objec public static final int MAX_LENGTH_ORGANISATION_UNIT = 64 public static final int MAX_LENGTH_STATE = 64 ## -public static final class net.corda.core.identity.CordaX500Name$Companion extends java.lang.Object +public static final class net.corda.core.identity.CordaX500Name$Companion extends java.lang.Object implements net.corda.core.internal.utilities.Internable public (kotlin.jvm.internal.DefaultConstructorMarker) @NotNull public final net.corda.core.identity.CordaX500Name build(javax.security.auth.x500.X500Principal) @NotNull + public net.corda.core.internal.utilities.PrivateInterner getInterner() + @NotNull public final net.corda.core.identity.CordaX500Name parse(String) ## public final class net.corda.core.identity.IdentityUtils extends java.lang.Object @@ -3262,6 +3449,8 @@ public final class net.corda.core.identity.Party extends net.corda.core.identity @NotNull public final net.corda.core.identity.AnonymousParty anonymise() @NotNull + public final String description() + @NotNull public final net.corda.core.identity.CordaX500Name getName() @NotNull public net.corda.core.identity.CordaX500Name nameOrNull() @@ -3269,6 +3458,14 @@ public final class net.corda.core.identity.Party extends net.corda.core.identity public net.corda.core.contracts.PartyAndReference ref(net.corda.core.utilities.OpaqueBytes) @NotNull public String toString() + public static final net.corda.core.identity.Party$Companion Companion +## +public static final class net.corda.core.identity.Party$Companion extends java.lang.Object + public (kotlin.jvm.internal.DefaultConstructorMarker) + @NotNull + public final net.corda.core.identity.Party create(java.security.cert.X509Certificate) + @NotNull + public final net.corda.core.identity.Party create(net.corda.core.identity.CordaX500Name, java.security.PublicKey) ## @CordaSerializable public final class net.corda.core.identity.PartyAndCertificate extends java.lang.Object @@ -3293,6 +3490,8 @@ public final class net.corda.core.identity.PartyAndCertificate extends java.lang public String toString() @NotNull public final java.security.cert.PKIXCertPathValidatorResult verify(java.security.cert.TrustAnchor) + @NotNull + public final java.security.cert.PKIXCertPathValidatorResult verify(java.util.Set) ## @CordaSerializable public interface net.corda.core.messaging.AllPossibleRecipients extends net.corda.core.messaging.MessageRecipients @@ -3330,6 +3529,8 @@ public interface net.corda.core.messaging.CordaRPCOps extends net.corda.core.mes @NotNull public abstract java.util.Map finishedFlowsWithClientIds() @NotNull + public abstract java.util.Map finishedFlowsWithClientIdsAsAdmin() + @NotNull public abstract net.corda.core.node.NetworkParameters getNetworkParameters() @NotNull public abstract Iterable getVaultTransactionNotes(net.corda.core.crypto.SecureHash) @@ -3374,6 +3575,7 @@ public interface net.corda.core.messaging.CordaRPCOps extends net.corda.core.mes @NotNull public abstract java.util.List registeredFlows() public abstract boolean removeClientId(String) + public abstract boolean removeClientIdAsAdmin(String) public abstract void setFlowsDrainingModeEnabled(boolean) public abstract void shutdown() @RPCReturnsObservables @@ -3691,6 +3893,11 @@ public static final class net.corda.core.messaging.StateMachineUpdate$Removed ex public String toString() ## @DoNotImplement +public interface net.corda.core.messaging.flows.FlowManagerRPCOps extends net.corda.core.messaging.RPCOps + public abstract void debugCheckpoints() + public abstract void dumpCheckpoints() +## +@DoNotImplement public interface net.corda.core.node.AppServiceHub extends net.corda.core.node.ServiceHub @NotNull public abstract net.corda.core.node.services.vault.CordaTransactionSupport getDatabase() @@ -3756,8 +3963,12 @@ public final class net.corda.core.node.NetworkParameters extends java.lang.Objec public final java.util.Map> getWhitelistedContractImplementations() public int hashCode() @NotNull + public final net.corda.core.node.NetworkParameters toImmutable() + @NotNull public String toString() ## +public final class net.corda.core.node.NetworkParametersKt extends java.lang.Object +## @CordaSerializable public final class net.corda.core.node.NodeDiagnosticInfo extends java.lang.Object public (String, String, int, String, java.util.List) @@ -5990,6 +6201,11 @@ public final class net.corda.core.serialization.SerializationAPIKt extends java. public static final net.corda.core.serialization.SerializedBytes serialize(T, net.corda.core.serialization.SerializationFactory, net.corda.core.serialization.SerializationContext) @NotNull public static final net.corda.core.serialization.SerializationContext withWhitelist(net.corda.core.serialization.SerializationContext, java.util.List>) + public static final int AMQP_ENVELOPE_CACHE_INITIAL_CAPACITY = 256 + @NotNull + public static final String AMQP_ENVELOPE_CACHE_PROPERTY = "AMQP_ENVELOPE_CACHE" + @NotNull + public static final String DESERIALIZATION_CACHE_PROPERTY = "DESERIALIZATION_CACHE" ## @DoNotImplement public interface net.corda.core.serialization.SerializationContext @@ -6030,6 +6246,8 @@ public interface net.corda.core.serialization.SerializationContext @NotNull public abstract net.corda.core.serialization.SerializationContext withPreventDataLoss() @NotNull + public abstract net.corda.core.serialization.SerializationContext withProperties(java.util.Map) + @NotNull public abstract net.corda.core.serialization.SerializationContext withProperty(Object, Object) @NotNull public abstract net.corda.core.serialization.SerializationContext withWhitelisted(Class) @@ -6090,6 +6308,8 @@ public interface net.corda.core.serialization.SerializationSchemeContext @NotNull public abstract ClassLoader getDeserializationClassLoader() @NotNull + public abstract java.util.Map getProperties() + @NotNull public abstract net.corda.core.serialization.ClassWhitelist getWhitelist() ## public interface net.corda.core.serialization.SerializationToken @@ -6206,15 +6426,23 @@ public final class net.corda.core.transactions.ComponentVisibilityException exte @DoNotImplement @CordaSerializable public final class net.corda.core.transactions.ContractUpgradeFilteredTransaction extends net.corda.core.transactions.CoreTransaction + @DeprecatedConstructorForDeserialization public (java.util.Map, java.util.Map) + public (java.util.Map, java.util.Map, net.corda.core.crypto.DigestService) @NotNull public final java.util.Map component1() @NotNull public final java.util.Map component2() @NotNull + public final net.corda.core.crypto.DigestService component3() + @NotNull public final net.corda.core.transactions.ContractUpgradeFilteredTransaction copy(java.util.Map, java.util.Map) + @NotNull + public final net.corda.core.transactions.ContractUpgradeFilteredTransaction copy(java.util.Map, java.util.Map, net.corda.core.crypto.DigestService) public boolean equals(Object) @NotNull + public final net.corda.core.crypto.DigestService getDigestService() + @NotNull public final java.util.Map getHiddenComponents() @NotNull public net.corda.core.crypto.SecureHash getId() @@ -6304,8 +6532,11 @@ public static final class net.corda.core.transactions.ContractUpgradeLedgerTrans @DoNotImplement @CordaSerializable public final class net.corda.core.transactions.ContractUpgradeWireTransaction extends net.corda.core.transactions.CoreTransaction + @DeprecatedConstructorForDeserialization public (java.util.List, net.corda.core.contracts.PrivacySalt) + @DeprecatedConstructorForDeserialization public (java.util.List, net.corda.core.contracts.PrivacySalt, int, kotlin.jvm.internal.DefaultConstructorMarker) + public (java.util.List, net.corda.core.contracts.PrivacySalt, net.corda.core.crypto.DigestService) @NotNull public final net.corda.core.transactions.ContractUpgradeFilteredTransaction buildFilteredTransaction() @NotNull @@ -6313,9 +6544,15 @@ public final class net.corda.core.transactions.ContractUpgradeWireTransaction ex @NotNull public final net.corda.core.contracts.PrivacySalt component2() @NotNull + public final net.corda.core.crypto.DigestService component3() + @NotNull public final net.corda.core.transactions.ContractUpgradeWireTransaction copy(java.util.List, net.corda.core.contracts.PrivacySalt) + @NotNull + public final net.corda.core.transactions.ContractUpgradeWireTransaction copy(java.util.List, net.corda.core.contracts.PrivacySalt, net.corda.core.crypto.DigestService) public boolean equals(Object) @NotNull + public final net.corda.core.crypto.DigestService getDigestService() + @NotNull public net.corda.core.crypto.SecureHash getId() @NotNull public java.util.List getInputs() @@ -6389,7 +6626,9 @@ public final class net.corda.core.transactions.FilteredComponentGroup extends ne @DoNotImplement @CordaSerializable public final class net.corda.core.transactions.FilteredTransaction extends net.corda.core.transactions.TraversableTransaction + @DeprecatedConstructorForDeserialization public (net.corda.core.crypto.SecureHash, java.util.List, java.util.List) + public (net.corda.core.crypto.SecureHash, java.util.List, java.util.List, net.corda.core.crypto.DigestService) @NotNull public static final net.corda.core.transactions.FilteredTransaction buildFilteredTransaction(net.corda.core.transactions.WireTransaction, java.util.function.Predicate) public final void checkAllComponentsVisible(net.corda.core.contracts.ComponentGroupEnum) @@ -6433,6 +6672,7 @@ public abstract class net.corda.core.transactions.FullTransaction extends net.co public final class net.corda.core.transactions.LedgerTransaction extends net.corda.core.transactions.FullTransaction public (java.util.List>, java.util.List>, java.util.List>, java.util.List, net.corda.core.crypto.SecureHash, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow, net.corda.core.contracts.PrivacySalt) public (java.util.List>, java.util.List>, java.util.List>, java.util.List, net.corda.core.crypto.SecureHash, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow, net.corda.core.contracts.PrivacySalt, net.corda.core.node.NetworkParameters) + public (java.util.List, java.util.List, java.util.List, java.util.List, net.corda.core.crypto.SecureHash, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow, net.corda.core.contracts.PrivacySalt, net.corda.core.node.NetworkParameters, java.util.List, java.util.List, java.util.List, java.util.List, kotlin.jvm.functions.Function1, kotlin.jvm.functions.Function2, net.corda.core.serialization.internal.AttachmentsClassLoaderCache, net.corda.core.crypto.DigestService, kotlin.jvm.internal.DefaultConstructorMarker) @NotNull public final java.util.List> commandsOfType(Class) @NotNull @@ -6491,6 +6731,8 @@ public final class net.corda.core.transactions.LedgerTransaction extends net.cor @NotNull public final java.util.List> getCommands() @NotNull + public final net.corda.core.crypto.DigestService getDigestService() + @NotNull public net.corda.core.crypto.SecureHash getId() @NotNull public final net.corda.core.contracts.ContractState getInput(int) @@ -6629,14 +6871,22 @@ public static final class net.corda.core.transactions.NotaryChangeLedgerTransact @DoNotImplement @CordaSerializable public final class net.corda.core.transactions.NotaryChangeWireTransaction extends net.corda.core.transactions.CoreTransaction + @DeprecatedConstructorForDeserialization public (java.util.List) + public (java.util.List, net.corda.core.crypto.DigestService) public (java.util.List, net.corda.core.identity.Party, net.corda.core.identity.Party) @NotNull public final java.util.List component1() @NotNull + public final net.corda.core.crypto.DigestService component2() + @NotNull public final net.corda.core.transactions.NotaryChangeWireTransaction copy(java.util.List) + @NotNull + public final net.corda.core.transactions.NotaryChangeWireTransaction copy(java.util.List, net.corda.core.crypto.DigestService) public boolean equals(Object) @NotNull + public final net.corda.core.crypto.DigestService getDigestService() + @NotNull public net.corda.core.crypto.SecureHash getId() @NotNull public java.util.List getInputs() @@ -6851,6 +7101,10 @@ public class net.corda.core.transactions.TransactionBuilder extends java.lang.Ob public final net.corda.core.transactions.SignedTransaction toSignedTransaction(net.corda.core.node.services.KeyManagementService, java.security.PublicKey, net.corda.core.crypto.SignatureMetadata, net.corda.core.node.ServicesForResolution) @NotNull public final net.corda.core.transactions.WireTransaction toWireTransaction(net.corda.core.node.ServicesForResolution) + @NotNull + public final net.corda.core.transactions.WireTransaction toWireTransaction(net.corda.core.node.ServicesForResolution, int) + @NotNull + public final net.corda.core.transactions.WireTransaction toWireTransaction(net.corda.core.node.ServicesForResolution, int, java.util.Map) public final void verify(net.corda.core.node.ServiceHub) @NotNull public final net.corda.core.transactions.TransactionBuilder withItems(Object...) @@ -6874,7 +7128,9 @@ public interface net.corda.core.transactions.TransactionWithSignatures extends n @DoNotImplement @CordaSerializable public abstract class net.corda.core.transactions.TraversableTransaction extends net.corda.core.transactions.CoreTransaction + @DeprecatedConstructorForDeserialization public (java.util.List) + public (java.util.List, net.corda.core.crypto.DigestService) @NotNull public final java.util.List getAttachments() @NotNull @@ -6884,6 +7140,8 @@ public abstract class net.corda.core.transactions.TraversableTransaction extends @NotNull public java.util.List getComponentGroups() @NotNull + public final net.corda.core.crypto.DigestService getDigestService() + @NotNull public java.util.List getInputs() @Nullable public net.corda.core.crypto.SecureHash getNetworkParametersHash() @@ -6903,8 +7161,11 @@ public final class net.corda.core.transactions.WireTransaction extends net.corda public (java.util.List, java.util.List, java.util.List>, java.util.List>, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow) public (java.util.List, java.util.List, java.util.List>, java.util.List>, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow, net.corda.core.contracts.PrivacySalt) public (java.util.List, java.util.List, java.util.List, java.util.List, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow, net.corda.core.contracts.PrivacySalt, int, kotlin.jvm.internal.DefaultConstructorMarker) + @DeprecatedConstructorForDeserialization public (java.util.List, net.corda.core.contracts.PrivacySalt) + @DeprecatedConstructorForDeserialization public (java.util.List, net.corda.core.contracts.PrivacySalt, int, kotlin.jvm.internal.DefaultConstructorMarker) + public (java.util.List, net.corda.core.contracts.PrivacySalt, net.corda.core.crypto.DigestService) @NotNull public final net.corda.core.transactions.FilteredTransaction buildFilteredTransaction(java.util.function.Predicate) public final void checkSignature(net.corda.core.crypto.TransactionSignature) @@ -7290,6 +7551,12 @@ public final class net.corda.core.utilities.SgxSupport extends java.lang.Object public static final boolean isInsideEnclave() public static final net.corda.core.utilities.SgxSupport INSTANCE ## +public final class net.corda.core.utilities.ThreadDumpUtilsKt extends java.lang.Object + @NotNull + public static final String asString(management.ThreadInfo, int) + @NotNull + public static final String threadDumpAsString() +## @CordaSerializable public abstract class net.corda.core.utilities.Try extends java.lang.Object public (kotlin.jvm.internal.DefaultConstructorMarker) @@ -7709,6 +7976,8 @@ public final class net.corda.testing.core.TestConstants extends java.lang.Object @NotNull public static final net.corda.core.identity.CordaX500Name CHARLIE_NAME @NotNull + public static final net.corda.core.identity.CordaX500Name DAVE_NAME + @NotNull public static final net.corda.core.identity.CordaX500Name DUMMY_BANK_A_NAME @NotNull public static final net.corda.core.identity.CordaX500Name DUMMY_BANK_B_NAME @@ -7752,6 +8021,7 @@ public static final class net.corda.testing.core.TestIdentity$Companion extends public final net.corda.testing.core.TestIdentity fresh(String, net.corda.core.crypto.SignatureScheme) ## public final class net.corda.testing.core.TestUtils extends java.lang.Object + public static final T executeTest(java.time.Duration, kotlin.jvm.functions.Function0, java.time.Duration, kotlin.jvm.functions.Function0) @NotNull public static final net.corda.core.utilities.NetworkHostAndPort freeLocalHostAndPort() public static final int freePort() @@ -8085,6 +8355,8 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O public (boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map, boolean, boolean, boolean, java.util.List, java.util.List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map, boolean, java.util.Collection, int, kotlin.jvm.internal.DefaultConstructorMarker) public (boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map, boolean, boolean, boolean, java.util.List, java.util.List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map, boolean, java.util.Collection, java.nio.file.Path, java.util.List, java.util.Map, boolean) public (boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map, boolean, boolean, boolean, java.util.List, java.util.List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map, boolean, java.util.Collection, java.nio.file.Path, java.util.List, java.util.Map, boolean, int, kotlin.jvm.internal.DefaultConstructorMarker) + public (boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map, boolean, boolean, boolean, java.util.List, java.util.List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map, boolean, java.util.Collection, java.nio.file.Path, java.util.List, java.util.Map, boolean, boolean) + public (boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map, boolean, boolean, boolean, java.util.List, java.util.List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map, boolean, java.util.Collection, java.nio.file.Path, java.util.List, java.util.Map, boolean, boolean, int, kotlin.jvm.internal.DefaultConstructorMarker) public (boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map, boolean, boolean, boolean, java.util.List, java.util.List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, boolean) public final boolean component1() @NotNull @@ -8107,6 +8379,7 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O public final boolean component19() @NotNull public final java.nio.file.Path component2() + public final boolean component20() @NotNull public final net.corda.testing.driver.PortAllocation component3() @NotNull @@ -8125,6 +8398,8 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O @NotNull public final net.corda.testing.driver.DriverParameters copy(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map, boolean, boolean, boolean, java.util.List, java.util.List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map, boolean, java.util.Collection, java.nio.file.Path, java.util.List, java.util.Map, boolean) @NotNull + public final net.corda.testing.driver.DriverParameters copy(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map, boolean, boolean, boolean, java.util.List, java.util.List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map, boolean, java.util.Collection, java.nio.file.Path, java.util.List, java.util.Map, boolean, boolean) + @NotNull public final net.corda.testing.driver.DriverParameters copy(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map, boolean, boolean, boolean, java.util.List, java.util.List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Set) public boolean equals(Object) public final boolean getAllowHibernateToManageAppSchema() @@ -8153,6 +8428,7 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O public final java.util.List getNotarySpecs() @NotNull public final net.corda.testing.driver.PortAllocation getPortAllocation() + public final boolean getPremigrateH2Database() public final boolean getStartNodesInProcess() @NotNull public final java.util.Map getSystemProperties() @@ -8265,6 +8541,8 @@ public final class net.corda.testing.driver.NodeParameters extends java.lang.Obj public (net.corda.core.identity.CordaX500Name, java.util.List, net.corda.testing.driver.VerifierType, java.util.Map, Boolean, String, java.util.Collection, java.util.Map, String, net.corda.core.utilities.NetworkHostAndPort, int, kotlin.jvm.internal.DefaultConstructorMarker) @Nullable public final net.corda.core.identity.CordaX500Name component1() + @Nullable + public final net.corda.core.utilities.NetworkHostAndPort component10() @NotNull public final java.util.List component2() @NotNull @@ -8300,6 +8578,8 @@ public final class net.corda.testing.driver.NodeParameters extends java.lang.Obj public final String getMaximumHeapSize() @Nullable public final net.corda.core.identity.CordaX500Name getProvidedName() + @Nullable + public final net.corda.core.utilities.NetworkHostAndPort getRpcAddress() @NotNull public final java.util.List getRpcUsers() @Nullable @@ -8435,6 +8715,11 @@ public static final class net.corda.testing.node.ClusterSpec$Raft extends net.co @NotNull public String toString() ## +public final class net.corda.testing.node.DatabaseSnapshot extends java.lang.Object + public final void copyDatabaseSnapshot(java.nio.file.Path) + public final java.nio.file.Path databaseFilename(java.nio.file.Path) + public static final net.corda.testing.node.DatabaseSnapshot INSTANCE +## @ThreadSafe public final class net.corda.testing.node.InMemoryMessagingNetwork extends net.corda.core.serialization.SingletonSerializeAsToken public (boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, org.apache.activemq.artemis.utils.ReusableLatch, kotlin.jvm.internal.DefaultConstructorMarker) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 5a9c828620..997f66a528 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -14,9 +14,8 @@