mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
11d0054fcc
* ENT-11055: Basic external verification Introduction of the external transaction verifier, a separate JVM process for verifying `SignedTransaction`s. The end goal is for this verifier to be built with Kotlin 1.2 so that it creates a compatible verification environment for transactions with 4.11 contracts. For now however the verifier is built against Kotlin 1.8, same as the node. External verification is enabled when the the system property `net.corda.node.verification.external` is set to `true`. When enabled, all verification requests made via `SignedTransaction.verify` are sent to the external verifier, regardless of the transaction content. It will do the vast bulk of the verification and then send the result back, namely if an exception occurred. If it did, then it's re-thrown in the node. The external verifier is a stateless process, with no connection to the node's database. All transaction resolution information needed to create the relevant ledger transaction object are made to the node, which waits in a loop servicing these requests until it receives the result. The verifier Jar is embedded in the Corda node Jar, and is extracted and run when needed for the first time. The node opens up a local port for the verifier to communicate with, which is specified to the verifier in the process command line. This all means there is no extra configuration or deployment required to support external verification. The existing code had some initial attempts and abstractions to support a future external verification feature. However, they were either incorrect or didn't quite fit. One such example was `TransactionVerifierService`. It incorrectly operated on the `LedgerTransaction` level, which doesn't work since the transaction needs to be first serialised. Instead a new abstraction, `VerificationSupport` has been introduced, which represents all the operations needed to resolve and verify a `SignedTransaction`, essentially replacing `ServicesForResolution` (a lot of the changes are due to this). The external verifier implements this with a simple RPC mechanism, whilst the node needed a new (internal) `ServiceHub` abstraction, `VerifyingServiceHub`. `ServicesForResolution` hasn't been deleted since it's public API, however all classes implementing it must also implement `VerifyingServiceHub`. This is possible to do without breaking compatibility since `ServicesForResolution` is annotated with `@DoNotImplement`. Changes to `api-current.txt` were made due to the removal of `TransactionVerifierService`, which was clearly indicated as an internal class, and returning `TransactionBuilder.toLedgerTransactionWithContext` back to an internal method. * Address review comments * One bulk load states method * Merge fix
354 lines
14 KiB
Groovy
354 lines
14 KiB
Groovy
plugins {
|
|
id 'com.google.cloud.tools.jib' version '0.9.4'
|
|
}
|
|
|
|
apply plugin: 'org.jetbrains.kotlin.jvm'
|
|
// Java Persistence API support: create no-arg constructor
|
|
// see: http://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell
|
|
apply plugin: 'org.jetbrains.kotlin.plugin.jpa'
|
|
apply plugin: 'java'
|
|
apply plugin: 'net.corda.plugins.quasar-utils'
|
|
apply plugin: 'corda.common-publishing'
|
|
|
|
description 'Corda node modules'
|
|
|
|
ext {
|
|
Properties constants = new Properties()
|
|
file("$rootDir/constants.properties").withInputStream { constants.load(it) }
|
|
|
|
jolokia_version = constants.getProperty('jolokiaAgentVersion')
|
|
}
|
|
|
|
//noinspection GroovyAssignabilityCheck
|
|
configurations {
|
|
integrationTestImplementation.extendsFrom testImplementation
|
|
integrationTestRuntimeOnly.extendsFrom testRuntimeOnly
|
|
|
|
slowIntegrationTestCompile.extendsFrom testImplementation
|
|
slowIntegrationTestRuntimeOnly.extendsFrom testRuntimeOnly
|
|
}
|
|
|
|
sourceSets {
|
|
integrationTest {
|
|
kotlin {
|
|
compileClasspath += main.output + test.output
|
|
runtimeClasspath += main.output + test.output
|
|
srcDir file('src/integration-test/kotlin')
|
|
}
|
|
java {
|
|
compileClasspath += main.output + test.output
|
|
runtimeClasspath += main.output + test.output
|
|
srcDir file('src/integration-test/java')
|
|
}
|
|
resources {
|
|
srcDir file('src/integration-test/resources')
|
|
}
|
|
}
|
|
slowIntegrationTest {
|
|
kotlin {
|
|
compileClasspath += main.output + test.output
|
|
runtimeClasspath += main.output + test.output
|
|
srcDir file('src/integration-test-slow/kotlin')
|
|
}
|
|
java {
|
|
compileClasspath += main.output + test.output
|
|
runtimeClasspath += main.output + test.output
|
|
srcDir file('src/integration-test-slow/java')
|
|
}
|
|
resources {
|
|
srcDir file('src/integration-test-slow/resources')
|
|
}
|
|
}
|
|
}
|
|
|
|
jib.container {
|
|
mainClass = "net.corda.node.Corda"
|
|
args = ['--log-to-console', '--no-local-shell', '--config-file=/config/node.conf']
|
|
// The Groovy string needs to be converted to a `java.lang.String` below.
|
|
jvmFlags = ['-Xmx1g', "-javaagent:/app/libs/quasar-core-${quasar_version}.jar".toString()]
|
|
}
|
|
|
|
// Use manual resource copying of log4j2.xml rather than source sets.
|
|
// This prevents problems in IntelliJ with regard to duplicate source roots.
|
|
processResources {
|
|
from file("$rootDir/config/dev/log4j2.xml")
|
|
from file("$rootDir/config/dev/jolokia-access.xml")
|
|
from(tasks.findByPath(":verifier:shadowJar")) {
|
|
into("net/corda/node/verification")
|
|
rename { "external-verifier.jar" }
|
|
}
|
|
}
|
|
|
|
processTestResources {
|
|
from file("$rootDir/config/test/jolokia-access.xml")
|
|
}
|
|
|
|
// To find potential version conflicts, run "gradle htmlDependencyReport" and then look in
|
|
// build/reports/project/dependencies/index.html for green highlighted parts of the tree.
|
|
|
|
dependencies {
|
|
implementation project(':core')
|
|
implementation project(':node-api')
|
|
implementation project(':client:rpc')
|
|
implementation project(':client:jackson')
|
|
implementation project(':tools:cliutils')
|
|
implementation project(':common-validation')
|
|
implementation project(':common-configuration-parsing')
|
|
implementation project(':common-logging')
|
|
implementation project(':serialization')
|
|
|
|
implementation "io.opentelemetry:opentelemetry-api:${open_telemetry_version}"
|
|
// Backwards compatibility goo: Apps expect confidential-identities to be loaded by default.
|
|
// We could eventually gate this on a target-version check.
|
|
implementation project(':confidential-identities')
|
|
|
|
// Log4J: logging framework (with SLF4J bindings)
|
|
implementation "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}"
|
|
implementation "org.apache.logging.log4j:log4j-web:${log4j_version}"
|
|
implementation "org.slf4j:jul-to-slf4j:$slf4j_version"
|
|
|
|
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
|
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
|
|
|
implementation "org.fusesource.jansi:jansi:$jansi_version"
|
|
implementation "com.google.guava:guava:$guava_version"
|
|
implementation "commons-io:commons-io:$commons_io_version"
|
|
|
|
// For caches rather than guava
|
|
implementation "com.github.ben-manes.caffeine:caffeine:$caffeine_version"
|
|
|
|
// For async logging
|
|
implementation "com.lmax:disruptor:$disruptor_version"
|
|
|
|
// Artemis: for reliable p2p message queues.
|
|
// TODO: remove the forced update of commons-collections and beanutils when artemis updates them
|
|
implementation "org.apache.commons:commons-collections4:${commons_collections_version}"
|
|
implementation "commons-beanutils:commons-beanutils:${beanutils_version}"
|
|
implementation("org.apache.activemq:artemis-server:${artemis_version}") {
|
|
exclude group: 'org.apache.commons', module: 'commons-dbcp2'
|
|
exclude group: 'org.jgroups', module: 'jgroups'
|
|
}
|
|
implementation("org.apache.activemq:artemis-core-client:${artemis_version}") {
|
|
exclude group: 'org.jgroups', module: 'jgroups'
|
|
}
|
|
// Bouncy castle support needed for X509 certificate manipulation
|
|
implementation "org.bouncycastle:bcprov-jdk18on:${bouncycastle_version}"
|
|
implementation "org.bouncycastle:bcpkix-jdk18on:${bouncycastle_version}"
|
|
|
|
implementation "com.esotericsoftware:kryo:$kryo_version"
|
|
|
|
implementation "com.fasterxml.jackson.core:jackson-annotations:${jackson_version}"
|
|
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
|
|
|
|
runtimeOnly("org.apache.activemq:artemis-amqp-protocol:${artemis_version}") {
|
|
// Gains our proton-j version from core module.
|
|
exclude group: 'org.apache.qpid', module: 'proton-j'
|
|
exclude group: 'org.jgroups', module: 'jgroups'
|
|
}
|
|
|
|
// Manifests: for reading stuff from the manifest file
|
|
implementation "com.jcabi:jcabi-manifests:$jcabi_manifests_version"
|
|
|
|
// Coda Hale's Metrics: for monitoring of key statistics
|
|
implementation "io.dropwizard.metrics:metrics-jmx:$metrics_version"
|
|
implementation "io.github.classgraph:classgraph:$class_graph_version"
|
|
implementation "org.liquibase:liquibase-core:$liquibase_version"
|
|
|
|
// TypeSafe Config: for simple and human friendly config files.
|
|
implementation "com.typesafe:config:$typesafe_config_version"
|
|
|
|
implementation "io.reactivex:rxjava:$rxjava_version"
|
|
|
|
implementation("org.apache.activemq:artemis-amqp-protocol:${artemis_version}") {
|
|
// Gains our proton-j version from core module.
|
|
exclude group: 'org.apache.qpid', module: 'proton-j'
|
|
exclude group: 'org.jgroups', module: 'jgroups'
|
|
}
|
|
|
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}"
|
|
testImplementation "junit:junit:$junit_version"
|
|
|
|
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}"
|
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
|
|
|
// Unit testing helpers.
|
|
testImplementation "org.assertj:assertj-core:${assertj_version}"
|
|
testImplementation project(':node-driver')
|
|
testImplementation project(':core-test-utils')
|
|
testImplementation project(':test-utils')
|
|
testImplementation project(':client:jfx')
|
|
testImplementation project(':finance:contracts')
|
|
testImplementation project(':finance:workflows')
|
|
|
|
// sample test schemas
|
|
testImplementation project(path: ':finance:contracts', configuration: 'testArtifacts')
|
|
|
|
// For H2 database support in persistence
|
|
implementation "com.h2database:h2:$h2_version"
|
|
|
|
// SQL connection pooling library
|
|
implementation "com.zaxxer:HikariCP:${hikari_version}"
|
|
|
|
// Hibernate: an object relational mapper for writing state objects to the database automatically.
|
|
implementation "org.hibernate:hibernate-core:$hibernate_version"
|
|
implementation "org.hibernate:hibernate-java8:$hibernate_version"
|
|
|
|
// OkHTTP: Simple HTTP library.
|
|
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
|
|
|
|
// Apache Shiro: authentication, authorization and session management.
|
|
implementation "org.apache.shiro:shiro-core:${shiro_version}"
|
|
|
|
//Picocli for command line interface
|
|
implementation "info.picocli:picocli:$picocli_version"
|
|
|
|
integrationTestImplementation project(":testing:cordapps:dbfailure:dbfcontracts")
|
|
|
|
// Integration test helpers
|
|
integrationTestImplementation "de.javakaffee:kryo-serializers:$kryo_serializer_version"
|
|
integrationTestImplementation "junit:junit:$junit_version"
|
|
integrationTestImplementation "org.assertj:assertj-core:${assertj_version}"
|
|
integrationTestImplementation "org.apache.qpid:qpid-jms-client:${protonj_version}"
|
|
integrationTestImplementation "net.i2p.crypto:eddsa:$eddsa_version"
|
|
|
|
// BFT-Smart dependencies
|
|
implementation 'com.github.bft-smart:library:master-v1.1-beta-g6215ec8-87'
|
|
|
|
// Java Atomix: RAFT library
|
|
implementation 'io.atomix.copycat:copycat-client:1.2.3'
|
|
implementation 'io.atomix.copycat:copycat-server:1.2.3'
|
|
implementation 'io.atomix.catalyst:catalyst-netty:1.1.2'
|
|
|
|
// Jetty dependencies for NetworkMapClient test.
|
|
// Web stuff: for HTTP[S] servlets
|
|
testImplementation "org.hamcrest:hamcrest-library:2.1"
|
|
testImplementation "org.eclipse.jetty:jetty-servlet:${jetty_version}"
|
|
testImplementation "org.eclipse.jetty:jetty-webapp:${jetty_version}"
|
|
testImplementation "javax.servlet:javax.servlet-api:${servlet_version}"
|
|
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"
|
|
testImplementation "com.google.jimfs:jimfs:1.1"
|
|
testImplementation "co.paralleluniverse:quasar-core:$quasar_version"
|
|
testImplementation "com.natpryce:hamkrest:$hamkrest_version"
|
|
|
|
// Jersey for JAX-RS implementation for use in Jetty
|
|
testImplementation "org.glassfish.jersey.core:jersey-server:${jersey_version}"
|
|
testImplementation "org.glassfish.jersey.containers:jersey-container-servlet-core:${jersey_version}"
|
|
testImplementation "org.glassfish.jersey.containers:jersey-container-jetty-http:${jersey_version}"
|
|
|
|
// Jolokia JVM monitoring agent, required to push logs through slf4j
|
|
implementation "org.jolokia:jolokia-jvm:${jolokia_version}:agent"
|
|
// Optional New Relic JVM reporter, used to push metrics to the configured account associated with a newrelic.yml configuration. See https://mvnrepository.com/artifact/com.palominolabs.metrics/metrics-new-relic
|
|
implementation "com.palominolabs.metrics:metrics-new-relic:${metrics_new_relic_version}"
|
|
|
|
// Adding native SSL library to allow using native SSL with Artemis and AMQP
|
|
implementation "io.netty:netty-tcnative-boringssl-static:$tcnative_version"
|
|
|
|
// Byteman for runtime (termination) rules injection on the running node
|
|
// Submission tool allowing to install rules on running nodes
|
|
slowIntegrationTestCompile "org.jboss.byteman:byteman-submit:4.0.11"
|
|
// The actual Byteman agent which should only be in the classpath of the out of process nodes
|
|
slowIntegrationTestCompile "org.jboss.byteman:byteman:4.0.11"
|
|
|
|
testImplementation(project(':test-cli'))
|
|
testImplementation(project(':test-utils'))
|
|
|
|
slowIntegrationTestCompile sourceSets.main.output
|
|
slowIntegrationTestCompile sourceSets.test.output
|
|
slowIntegrationTestCompile configurations.implementation
|
|
slowIntegrationTestCompile configurations.testImplementation
|
|
slowIntegrationTestRuntimeOnly configurations.runtimeOnly
|
|
slowIntegrationTestRuntimeOnly configurations.testRuntimeOnly
|
|
|
|
integrationTestImplementation project(":testing:cordapps:missingmigration")
|
|
|
|
testImplementation project(':testing:cordapps:dbfailure:dbfworkflows')
|
|
|
|
// used by FinalityFlowErrorHandlingTest
|
|
slowIntegrationTestImplementation project(':testing:cordapps:cashobservers')
|
|
}
|
|
|
|
tasks.withType(JavaCompile).configureEach {
|
|
// Resolves a Gradle warning about not scanning for pre-processors.
|
|
options.compilerArgs << '-proc:none'
|
|
}
|
|
|
|
tasks.withType(Test).configureEach {
|
|
jvmArgs '-Djdk.attach.allowAttachSelf=true'
|
|
}
|
|
|
|
tasks.register('integrationTest', Test) {
|
|
testClassesDirs = sourceSets.integrationTest.output.classesDirs
|
|
classpath = sourceSets.integrationTest.runtimeClasspath
|
|
maxParallelForks = (System.env.CORDA_NODE_INT_TESTING_FORKS == null) ? 1 : "$System.env.CORDA_NODE_INT_TESTING_FORKS".toInteger()
|
|
|
|
jvmArgs test_add_opens
|
|
jvmArgs test_add_exports
|
|
|
|
// CertificateRevocationListNodeTests
|
|
systemProperty 'net.corda.dpcrl.connect.timeout', '4000'
|
|
}
|
|
|
|
tasks.register('slowIntegrationTest', Test) {
|
|
testClassesDirs = sourceSets.slowIntegrationTest.output.classesDirs
|
|
classpath = sourceSets.slowIntegrationTest.runtimeClasspath
|
|
maxParallelForks = 1
|
|
|
|
jvmArgs test_add_opens
|
|
jvmArgs test_add_exports
|
|
}
|
|
|
|
// quasar exclusions upon agent code instrumentation at run-time
|
|
quasar {
|
|
excludeClassLoaders.addAll(
|
|
'net.corda.core.serialization.internal.**'
|
|
)
|
|
excludePackages.addAll(
|
|
"antlr**",
|
|
"com.codahale**",
|
|
"com.fasterxml.**",
|
|
"com.github.benmanes.caffeine.**",
|
|
"com.google.**",
|
|
"com.lmax.**",
|
|
"com.zaxxer.**",
|
|
"net.bytebuddy**",
|
|
"io.github.classgraph**",
|
|
"io.netty*",
|
|
"liquibase**",
|
|
"net.i2p.crypto.**",
|
|
"nonapi.io.github.classgraph.**",
|
|
"org.apiguardian.**",
|
|
"org.bouncycastle**",
|
|
"org.codehaus.**",
|
|
"org.h2**",
|
|
"org.hibernate**",
|
|
"org.jboss.**",
|
|
"org.objenesis**",
|
|
"org.w3c.**",
|
|
"org.xml**",
|
|
"org.yaml**",
|
|
"rx**",
|
|
"io.opentelemetry.**")
|
|
}
|
|
|
|
jar {
|
|
baseName 'corda-node'
|
|
manifest {
|
|
attributes('Add-Opens': 'java.base/java.time java.base/java.io java.base/java.util java.base/java.net')
|
|
}
|
|
}
|
|
|
|
tasks.named('test', Test) {
|
|
maxHeapSize = "3g"
|
|
maxParallelForks = (System.env.CORDA_NODE_TESTING_FORKS == null) ? 1 : "$System.env.CORDA_NODE_TESTING_FORKS".toInteger()
|
|
}
|
|
|
|
publishing {
|
|
publications {
|
|
maven(MavenPublication) {
|
|
artifactId jar.baseName
|
|
from components.java
|
|
}
|
|
}
|
|
}
|