ENT-2967 Fix up use of various JDK performance contention points (#4608)

* ENT-2967 Various JDK contention points

* Move new private method to bottom of class.
This commit is contained in:
Rick Parker 2019-01-22 11:19:51 +00:00 committed by GitHub
parent ee4f4f5702
commit 197a13611d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 9 deletions

View File

@ -290,7 +290,7 @@ object Crypto {
fun decodePrivateKey(encodedKey: ByteArray): PrivateKey {
val keyInfo = PrivateKeyInfo.getInstance(encodedKey)
val signatureScheme = findSignatureScheme(keyInfo.privateKeyAlgorithm)
val keyFactory = KeyFactory.getInstance(signatureScheme.algorithmName, providerMap[signatureScheme.providerName])
val keyFactory = keyFactory(signatureScheme)
return keyFactory.generatePrivate(PKCS8EncodedKeySpec(encodedKey))
}
@ -323,7 +323,7 @@ object Crypto {
"Unsupported key/algorithm for schemeCodeName: ${signatureScheme.schemeCodeName}"
}
try {
val keyFactory = KeyFactory.getInstance(signatureScheme.algorithmName, providerMap[signatureScheme.providerName])
val keyFactory = keyFactory(signatureScheme)
return keyFactory.generatePrivate(PKCS8EncodedKeySpec(encodedKey))
} catch (ikse: InvalidKeySpecException) {
throw InvalidKeySpecException("This private key cannot be decoded, please ensure it is PKCS8 encoded and that " +
@ -342,7 +342,7 @@ object Crypto {
fun decodePublicKey(encodedKey: ByteArray): PublicKey {
val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(encodedKey)
val signatureScheme = findSignatureScheme(subjectPublicKeyInfo.algorithm)
val keyFactory = KeyFactory.getInstance(signatureScheme.algorithmName, providerMap[signatureScheme.providerName])
val keyFactory = keyFactory(signatureScheme)
return keyFactory.generatePublic(X509EncodedKeySpec(encodedKey))
}
@ -377,7 +377,7 @@ object Crypto {
"Unsupported key/algorithm for schemeCodeName: ${signatureScheme.schemeCodeName}"
}
try {
val keyFactory = KeyFactory.getInstance(signatureScheme.algorithmName, providerMap[signatureScheme.providerName])
val keyFactory = keyFactory(signatureScheme)
return keyFactory.generatePublic(X509EncodedKeySpec(encodedKey))
} catch (ikse: InvalidKeySpecException) {
throw throw InvalidKeySpecException("This public key cannot be decoded, please ensure it is X509 encoded and " +
@ -1063,4 +1063,8 @@ object Crypto {
private fun setBouncyCastleRNG() {
CryptoServicesRegistrar.setSecureRandom(newSecureRandom())
}
private fun keyFactory(signatureScheme: SignatureScheme) = signatureScheme.getKeyFactory {
KeyFactory.getInstance(signatureScheme.algorithmName, providerMap[signatureScheme.providerName])
}
}

View File

@ -2,6 +2,7 @@ package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import org.bouncycastle.asn1.x509.AlgorithmIdentifier
import java.security.KeyFactory
import java.security.Signature
import java.security.spec.AlgorithmParameterSpec
@ -33,4 +34,15 @@ data class SignatureScheme(
val algSpec: AlgorithmParameterSpec?,
val keySize: Int?,
val desc: String
)
) {
@Volatile
private var memoizedKeyFactory: KeyFactory? = null
internal fun getKeyFactory(factoryFactory: () -> KeyFactory): KeyFactory {
return memoizedKeyFactory ?: run {
val newFactory = factoryFactory()
memoizedKeyFactory = newFactory
newFactory
}
}
}

View File

@ -124,7 +124,7 @@ internal fun checkConstraintValidity(state: TransactionState<*>) {
*/
internal fun ContractClassName.contractHasAutomaticConstraintPropagation(classLoader: ClassLoader? = null): Boolean {
return (classLoader ?: NoConstraintPropagation::class.java.classLoader)
.loadClass(this)
.run { Class.forName(this@contractHasAutomaticConstraintPropagation, false, this) }
.getAnnotation(NoConstraintPropagation::class.java) == null
}

View File

@ -24,7 +24,6 @@ class IncompatibleTypeIdentifierException(message: String) : NotSerializableExce
* [TypeIdentifier] provides a family of type identifiers, together with a [prettyPrint] method for displaying them.
*/
sealed class TypeIdentifier {
/**
* The name of the type.
*/
@ -38,7 +37,7 @@ sealed class TypeIdentifier {
* @throws IncompatibleTypeIdentifierException if the type identifier is incompatible with the locally-defined type
* to which it refers.
*/
abstract fun getLocalType(classLoader: ClassLoader = ClassLoader.getSystemClassLoader()): Type
abstract fun getLocalType(classLoader: ClassLoader = systemClassLoader): Type
open val erased: TypeIdentifier get() = this
@ -61,6 +60,9 @@ sealed class TypeIdentifier {
if (simplifyClassNames) split(".", "$").last() else this
companion object {
// This method has locking. So we memo the value here.
private val systemClassLoader: ClassLoader = ClassLoader.getSystemClassLoader()
/**
* Obtain the [TypeIdentifier] for an erased Java class.
*
@ -204,7 +206,7 @@ sealed class TypeIdentifier {
override fun toString() = "Parameterised(${prettyPrint()})"
override fun getLocalType(classLoader: ClassLoader): Type {
val rawType = classLoader.loadClass(name)
val rawType = Class.forName(name, false, classLoader)
if (rawType.typeParameters.size != parameters.size) {
throw IncompatibleTypeIdentifierException(
"Class $rawType expects ${rawType.typeParameters.size} type arguments, " +