corda/serialization-deterministic/build.gradle
Chris Rankin caeafb8201
ENT-6357: Deserialize LedgerTransaction elements for each Contract.verify(). (#6962)
* ENT-6357: Deserialize LedgerTransaction elements for each Contract.verify().

* Lock the LedgerTransaction and NetworkParameters objects down for contract verification.

* Refactor BasicVerifier to be package private instead of public.

* Simplify verifyConstraints() operation.

* Review fixes: replace HashSet with LinkedHashSet, and add signing parties to commands via mapIndexed.

* Ensure tests also run notary nodes "out of process".

* Streamline SerializationContext switching.

* Cache deserialised cryptographic instances during contract verification.

* Invoke Class.forName() instead of ClassLoader.loadClass() to reduce contention on the system classloader's lock.

* Deserialization cache key now pre-computes its hash code.

* Allow AttachmentsClassLoader to be used concurrently.

* Cache all Envelope objects for reuse during contract verification.

* Generate CertPathProxy hash code using conventional algorithm.

* Adjust CustomSerializer.Proxy to allow better access to SerializationContext.
2021-11-10 16:38:40 +00:00

229 lines
6.6 KiB
Groovy

import net.corda.gradle.jarfilter.JarFilterTask
import net.corda.gradle.jarfilter.MetaFixerTask
import proguard.gradle.ProGuardTask
import static org.gradle.api.JavaVersion.VERSION_1_8
plugins {
id 'org.jetbrains.kotlin.jvm'
id 'net.corda.plugins.publish-utils'
id 'com.jfrog.artifactory'
id 'java-library'
id 'idea'
}
apply from: "${rootProject.projectDir}/deterministic.gradle"
description 'Corda serialization (deterministic)'
evaluationDependsOn(":serialization")
// required by DJVM and Avian JVM (for running inside the SGX enclave) which only supports Java 8.
targetCompatibility = VERSION_1_8
def javaHome = System.getProperty('java.home')
def jarBaseName = "corda-${project.name}".toString()
configurations {
deterministicLibraries {
canBeConsumed = false
extendsFrom implementation
}
deterministicArtifacts.extendsFrom deterministicLibraries
}
dependencies {
compileOnly project(':serialization')
// Configure these by hand. It should be a minimal subset of dependencies,
// and without any obviously non-deterministic ones such as Hibernate.
// These dependencies will become "compile" scoped in our published POM.
// See publish.dependenciesFrom.defaultScope.
deterministicLibraries project(path: ':core-deterministic', configuration: 'deterministicArtifacts')
deterministicLibraries "org.apache.qpid:proton-j:$protonj_version"
// These "implementation" dependencies will become "runtime" scoped in our published POM.
implementation "org.iq80.snappy:snappy:$snappy_version"
implementation "com.google.guava:guava:$guava_version"
}
tasks.named('jar', Jar) {
archiveBaseName = 'DOES-NOT-EXIST'
// Don't build a jar here because it would be the wrong one.
// The jar we really want will be built by the metafix task.
enabled = false
}
def serializationJarTask = project(':serialization').tasks.named('jar', Jar)
def originalJar = serializationJarTask.map { it.outputs.files.singleFile }
def patchSerialization = tasks.register('patchSerialization', Zip) {
dependsOn serializationJarTask
destinationDirectory = layout.buildDirectory.dir('source-libs')
metadataCharset 'UTF-8'
archiveClassifier = 'transient'
archiveExtension = 'jar'
from(compileKotlin)
from(processResources)
from(zipTree(originalJar)) {
exclude 'net/corda/serialization/internal/AttachmentsClassLoaderBuilder*'
exclude 'net/corda/serialization/internal/ByteBufferStreams*'
exclude 'net/corda/serialization/internal/DefaultWhitelist*'
exclude 'net/corda/serialization/internal/amqp/AMQPSerializerFactories*'
exclude 'net/corda/serialization/internal/amqp/AMQPStreams*'
exclude 'net/corda/serialization/internal/amqp/AMQPSerializationThreadContext*'
exclude 'net/corda/serialization/internal/model/DefaultCacheProvider*'
}
reproducibleFileOrder = true
includeEmptyDirs = false
}
def predeterminise = tasks.register('predeterminise', ProGuardTask) {
dependsOn project(':core-deterministic').tasks.named('assemble')
injars patchSerialization
outjars file("$buildDir/proguard/pre-deterministic-${project.version}.jar")
if (JavaVersion.current().isJava9Compatible()) {
libraryjars "$javaHome/jmods"
} else {
libraryjars file("$javaHome/lib/rt.jar")
libraryjars file("$javaHome/lib/jce.jar")
libraryjars file("$javaHome/lib/ext/sunec.jar")
}
configurations.compileClasspath.forEach {
if (originalJar != it) {
libraryjars it, filter: '!META-INF/versions/**'
}
}
keepattributes '*'
keepdirectories
dontpreverify
dontobfuscate
dontoptimize
dontnote
printseeds
verbose
keep '@net.corda.core.KeepForDJVM class * { *; }', includedescriptorclasses:true
keepclassmembers 'class net.corda.serialization.** { public synthetic <methods>; }'
}
def jarFilter = tasks.register('jarFilter', JarFilterTask) {
jars predeterminise
annotations {
forDelete = [
"net.corda.core.DeleteForDJVM"
]
forStub = [
"net.corda.core.StubOutForDJVM"
]
forRemove = [
"co.paralleluniverse.fibers.Suspendable"
]
forSanitise = [
"net.corda.core.DeleteForDJVM"
]
}
}
def determinise = tasks.register('determinise', ProGuardTask) {
injars jarFilter
outjars file("$buildDir/proguard/$jarBaseName-${project.version}.jar")
if (JavaVersion.current().isJava9Compatible()) {
libraryjars "$javaHome/jmods"
} else {
libraryjars file("$javaHome/lib/rt.jar")
libraryjars file("$javaHome/lib/jce.jar")
}
configurations.deterministicLibraries.forEach {
libraryjars it, filter: '!META-INF/versions/**'
}
// Analyse the JAR for dead code, and remove (some of) it.
optimizations 'code/removal/simple,code/removal/advanced'
printconfiguration
keepattributes '*'
keepdirectories
dontobfuscate
dontnote
printseeds
verbose
keep '@net.corda.core.KeepForDJVM class * { *; }', includedescriptorclasses:true
keepclassmembers 'class net.corda.serialization.** { public synthetic <methods>; }'
}
def checkDeterminism = tasks.register('checkDeterminism', ProGuardTask)
def metafix = tasks.register('metafix', MetaFixerTask) {
outputDir = layout.buildDirectory.dir('libs')
jars determinise
suffix ""
// Strip timestamps from the JAR to make it reproducible.
preserveTimestamps = false
finalizedBy checkDeterminism
}
checkDeterminism.configure {
dependsOn jdkTask
injars metafix
libraryjars deterministic_rt_jar
configurations.deterministicLibraries.forEach {
libraryjars it, filter: '!META-INF/versions/**'
}
keepattributes '*'
dontpreverify
dontobfuscate
dontoptimize
verbose
keep 'class *'
}
defaultTasks "determinise"
determinise.configure {
finalizedBy metafix
}
tasks.named('assemble') {
dependsOn checkDeterminism
}
def deterministicJar = metafix.map { it.outputs.files.singleFile }
artifacts {
deterministicArtifacts deterministicJar
publish deterministicJar
}
tasks.named('sourceJar', Jar) {
from 'README.md'
include 'README.md'
}
tasks.named('javadocJar', Jar) {
from 'README.md'
include 'README.md'
}
publish {
dependenciesFrom(configurations.deterministicArtifacts) {
defaultScope = 'compile'
}
name jarBaseName
}
idea {
module {
if (project.hasProperty("deterministic_idea_sdk")) {
jdkName project.property("deterministic_idea_sdk") as String
}
}
}