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).
This commit is contained in:
Rick Parker 2022-10-18 09:28:41 +01:00 committed by GitHub
parent 3238638f22
commit b29713d7b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 707 additions and 82 deletions

View File

@ -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 <init>()
public <init>(int)
public <init>(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 <init>(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 <init>(net.corda.core.contracts.StateAndRef<? extends T>)
@ -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 <init>(kotlin.jvm.internal.DefaultConstructorMarker)
@NotNull
public final net.corda.core.contracts.SignatureAttachmentConstraint create(java.security.PublicKey)
@NotNull
public net.corda.core.internal.utilities.PrivateInterner<net.corda.core.contracts.SignatureAttachmentConstraint> getInterner()
##
public final class net.corda.core.contracts.SourceAndAmount extends java.lang.Object
public <init>(P, net.corda.core.contracts.Amount<T>, 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<T> withoutIssuer(net.corda.core.contracts.Amount<net.corda.core.contracts.Issued<T>>)
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 <init>(net.corda.core.crypto.SecureHash)
##
@CordaSerializable
public static final class net.corda.core.contracts.TransactionVerificationException$BrokenTransactionException extends net.corda.core.contracts.TransactionVerificationException
public <init>(net.corda.core.crypto.SecureHash, String)
##
@ -1257,6 +1280,10 @@ public static final class net.corda.core.contracts.TransactionVerificationExcept
public <init>(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 <init>(net.corda.core.crypto.SecureHash)
##
@CordaSerializable
public static final class net.corda.core.contracts.TransactionVerificationException$UntrustedAttachmentsException extends net.corda.core.CordaException
public <init>(net.corda.core.crypto.SecureHash, java.util.List<? extends net.corda.core.crypto.SecureHash>)
@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 <init>(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 <init>(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 <init>(byte[])
##
@ -1888,6 +1962,8 @@ public static final class net.corda.core.crypto.MerkleTree$Companion extends jav
public <init>(kotlin.jvm.internal.DefaultConstructorMarker)
@NotNull
public final net.corda.core.crypto.MerkleTree getMerkleTree(java.util.List<? extends net.corda.core.crypto.SecureHash>)
@NotNull
public final net.corda.core.crypto.MerkleTree getMerkleTree(java.util.List<? extends net.corda.core.crypto.SecureHash>, net.corda.core.crypto.DigestService)
##
public static final class net.corda.core.crypto.MerkleTree$Leaf extends net.corda.core.crypto.MerkleTree
public <init>(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 <init>(net.corda.core.crypto.PartialMerkleTree$PartialTree, net.corda.core.crypto.PartialMerkleTree$PartialTree)
public <init>(net.corda.core.crypto.PartialMerkleTree$PartialTree, net.corda.core.crypto.PartialMerkleTree$PartialTree, String)
public <init>(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 <init>(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 <init>(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<net.corda.core.crypto.SecureHash> 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 <init>(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 <init>(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 <init>(net.corda.core.flows.FlowExternalAsyncOperation<R>)
@NotNull
public net.corda.core.concurrent.CordaFuture<R> execute(String)
@NotNull
public final net.corda.core.flows.FlowExternalAsyncOperation<R> getOperation()
##
@CordaSerializable
public final class net.corda.core.flows.WrappedFlowExternalOperation extends java.lang.Object implements net.corda.core.internal.FlowAsyncOperation
public <init>(net.corda.core.internal.ServiceHubCoreInternal, net.corda.core.flows.FlowExternalOperation<R>)
@NotNull
public net.corda.core.concurrent.CordaFuture<R> execute(String)
@NotNull
public final net.corda.core.flows.FlowExternalOperation<R> 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 <init>(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 <init>(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<net.corda.core.identity.CordaX500Name> 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 <init>(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<? extends java.security.cert.TrustAnchor>)
##
@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<String, Boolean> finishedFlowsWithClientIds()
@NotNull
public abstract java.util.Map<String, Boolean> finishedFlowsWithClientIdsAsAdmin()
@NotNull
public abstract net.corda.core.node.NetworkParameters getNetworkParameters()
@NotNull
public abstract Iterable<String> 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<String> 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<String, java.util.List<net.corda.core.crypto.SecureHash>> 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 <init>(String, String, int, String, java.util.List<net.corda.core.cordapp.CordappInfo>)
@ -5990,6 +6201,11 @@ public final class net.corda.core.serialization.SerializationAPIKt extends java.
public static final net.corda.core.serialization.SerializedBytes<T> 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<? extends Class<?>>)
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<Object, ?>)
@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<Object, Object> 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 <init>(java.util.Map<Integer, net.corda.core.transactions.ContractUpgradeFilteredTransaction$FilteredComponent>, java.util.Map<Integer, ? extends net.corda.core.crypto.SecureHash>)
public <init>(java.util.Map<Integer, net.corda.core.transactions.ContractUpgradeFilteredTransaction$FilteredComponent>, java.util.Map<Integer, ? extends net.corda.core.crypto.SecureHash>, net.corda.core.crypto.DigestService)
@NotNull
public final java.util.Map<Integer, net.corda.core.transactions.ContractUpgradeFilteredTransaction$FilteredComponent> component1()
@NotNull
public final java.util.Map<Integer, net.corda.core.crypto.SecureHash> component2()
@NotNull
public final net.corda.core.crypto.DigestService component3()
@NotNull
public final net.corda.core.transactions.ContractUpgradeFilteredTransaction copy(java.util.Map<Integer, net.corda.core.transactions.ContractUpgradeFilteredTransaction$FilteredComponent>, java.util.Map<Integer, ? extends net.corda.core.crypto.SecureHash>)
@NotNull
public final net.corda.core.transactions.ContractUpgradeFilteredTransaction copy(java.util.Map<Integer, net.corda.core.transactions.ContractUpgradeFilteredTransaction$FilteredComponent>, java.util.Map<Integer, ? extends net.corda.core.crypto.SecureHash>, net.corda.core.crypto.DigestService)
public boolean equals(Object)
@NotNull
public final net.corda.core.crypto.DigestService getDigestService()
@NotNull
public final java.util.Map<Integer, net.corda.core.crypto.SecureHash> 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 <init>(java.util.List<? extends net.corda.core.utilities.OpaqueBytes>, net.corda.core.contracts.PrivacySalt)
@DeprecatedConstructorForDeserialization
public <init>(java.util.List, net.corda.core.contracts.PrivacySalt, int, kotlin.jvm.internal.DefaultConstructorMarker)
public <init>(java.util.List<? extends net.corda.core.utilities.OpaqueBytes>, 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<? extends net.corda.core.utilities.OpaqueBytes>, net.corda.core.contracts.PrivacySalt)
@NotNull
public final net.corda.core.transactions.ContractUpgradeWireTransaction copy(java.util.List<? extends net.corda.core.utilities.OpaqueBytes>, 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<net.corda.core.contracts.StateRef> 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 <init>(net.corda.core.crypto.SecureHash, java.util.List<net.corda.core.transactions.FilteredComponentGroup>, java.util.List<? extends net.corda.core.crypto.SecureHash>)
public <init>(net.corda.core.crypto.SecureHash, java.util.List<net.corda.core.transactions.FilteredComponentGroup>, java.util.List<? extends net.corda.core.crypto.SecureHash>, net.corda.core.crypto.DigestService)
@NotNull
public static final net.corda.core.transactions.FilteredTransaction buildFilteredTransaction(net.corda.core.transactions.WireTransaction, java.util.function.Predicate<Object>)
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 <init>(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends net.corda.core.contracts.ContractState>>, java.util.List<? extends net.corda.core.contracts.TransactionState<? extends net.corda.core.contracts.ContractState>>, java.util.List<? extends net.corda.core.contracts.CommandWithParties<? extends net.corda.core.contracts.CommandData>>, java.util.List<? extends net.corda.core.contracts.Attachment>, net.corda.core.crypto.SecureHash, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow, net.corda.core.contracts.PrivacySalt)
public <init>(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends net.corda.core.contracts.ContractState>>, java.util.List<? extends net.corda.core.contracts.TransactionState<? extends net.corda.core.contracts.ContractState>>, java.util.List<? extends net.corda.core.contracts.CommandWithParties<? extends net.corda.core.contracts.CommandData>>, java.util.List<? extends net.corda.core.contracts.Attachment>, 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 <init>(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<net.corda.core.contracts.Command<T>> commandsOfType(Class<T>)
@NotNull
@ -6491,6 +6731,8 @@ public final class net.corda.core.transactions.LedgerTransaction extends net.cor
@NotNull
public final java.util.List<net.corda.core.contracts.CommandWithParties<net.corda.core.contracts.CommandData>> 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 <init>(java.util.List<? extends net.corda.core.utilities.OpaqueBytes>)
public <init>(java.util.List<? extends net.corda.core.utilities.OpaqueBytes>, net.corda.core.crypto.DigestService)
public <init>(java.util.List<net.corda.core.contracts.StateRef>, net.corda.core.identity.Party, net.corda.core.identity.Party)
@NotNull
public final java.util.List<net.corda.core.utilities.OpaqueBytes> component1()
@NotNull
public final net.corda.core.crypto.DigestService component2()
@NotNull
public final net.corda.core.transactions.NotaryChangeWireTransaction copy(java.util.List<? extends net.corda.core.utilities.OpaqueBytes>)
@NotNull
public final net.corda.core.transactions.NotaryChangeWireTransaction copy(java.util.List<? extends net.corda.core.utilities.OpaqueBytes>, 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<net.corda.core.contracts.StateRef> 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<Object, ?>)
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 <init>(java.util.List<? extends net.corda.core.transactions.ComponentGroup>)
public <init>(java.util.List<? extends net.corda.core.transactions.ComponentGroup>, net.corda.core.crypto.DigestService)
@NotNull
public final java.util.List<net.corda.core.crypto.SecureHash> getAttachments()
@NotNull
@ -6884,6 +7140,8 @@ public abstract class net.corda.core.transactions.TraversableTransaction extends
@NotNull
public java.util.List<net.corda.core.transactions.ComponentGroup> getComponentGroups()
@NotNull
public final net.corda.core.crypto.DigestService getDigestService()
@NotNull
public java.util.List<net.corda.core.contracts.StateRef> 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 <init>(java.util.List<net.corda.core.contracts.StateRef>, java.util.List<? extends net.corda.core.crypto.SecureHash>, java.util.List<? extends net.corda.core.contracts.TransactionState<? extends net.corda.core.contracts.ContractState>>, java.util.List<? extends net.corda.core.contracts.Command<?>>, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow)
public <init>(java.util.List<net.corda.core.contracts.StateRef>, java.util.List<? extends net.corda.core.crypto.SecureHash>, java.util.List<? extends net.corda.core.contracts.TransactionState<? extends net.corda.core.contracts.ContractState>>, java.util.List<? extends net.corda.core.contracts.Command<?>>, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow, net.corda.core.contracts.PrivacySalt)
public <init>(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 <init>(java.util.List<? extends net.corda.core.transactions.ComponentGroup>, net.corda.core.contracts.PrivacySalt)
@DeprecatedConstructorForDeserialization
public <init>(java.util.List, net.corda.core.contracts.PrivacySalt, int, kotlin.jvm.internal.DefaultConstructorMarker)
public <init>(java.util.List<? extends net.corda.core.transactions.ComponentGroup>, net.corda.core.contracts.PrivacySalt, net.corda.core.crypto.DigestService)
@NotNull
public final net.corda.core.transactions.FilteredTransaction buildFilteredTransaction(java.util.function.Predicate<Object>)
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 <init>(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<kotlin.Unit>, java.time.Duration, kotlin.jvm.functions.Function0<? extends T>)
@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 <init>(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 <init>(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map<String, String>, boolean, boolean, boolean, java.util.List<net.corda.testing.node.NotarySpec>, java.util.List<String>, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map<String, ?>, boolean, java.util.Collection<? extends net.corda.testing.node.TestCordapp>, java.nio.file.Path, java.util.List<? extends java.nio.file.Path>, java.util.Map<String, String>, boolean)
public <init>(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 <init>(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map<String, String>, boolean, boolean, boolean, java.util.List<net.corda.testing.node.NotarySpec>, java.util.List<String>, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map<String, ?>, boolean, java.util.Collection<? extends net.corda.testing.node.TestCordapp>, java.nio.file.Path, java.util.List<? extends java.nio.file.Path>, java.util.Map<String, String>, boolean, boolean)
public <init>(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 <init>(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, java.util.Map<String, String>, boolean, boolean, boolean, java.util.List<net.corda.testing.node.NotarySpec>, java.util.List<String>, 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<String, String>, boolean, boolean, boolean, java.util.List<net.corda.testing.node.NotarySpec>, java.util.List<String>, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map<String, ?>, boolean, java.util.Collection<? extends net.corda.testing.node.TestCordapp>, java.nio.file.Path, java.util.List<? extends java.nio.file.Path>, java.util.Map<String, String>, 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<String, String>, boolean, boolean, boolean, java.util.List<net.corda.testing.node.NotarySpec>, java.util.List<String>, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Map<String, ?>, boolean, java.util.Collection<? extends net.corda.testing.node.TestCordapp>, java.nio.file.Path, java.util.List<? extends java.nio.file.Path>, java.util.Map<String, String>, 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<String, String>, boolean, boolean, boolean, java.util.List<net.corda.testing.node.NotarySpec>, java.util.List<String>, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, java.util.Set<? extends net.corda.testing.node.TestCordapp>)
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<net.corda.testing.node.NotarySpec> getNotarySpecs()
@NotNull
public final net.corda.testing.driver.PortAllocation getPortAllocation()
public final boolean getPremigrateH2Database()
public final boolean getStartNodesInProcess()
@NotNull
public final java.util.Map<String, String> getSystemProperties()
@ -8265,6 +8541,8 @@ public final class net.corda.testing.driver.NodeParameters extends java.lang.Obj
public <init>(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<net.corda.testing.node.User> 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<net.corda.testing.node.User> 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 <init>(boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, org.apache.activemq.artemis.utils.ReusableLatch, kotlin.jvm.internal.DefaultConstructorMarker)

View File

@ -14,9 +14,8 @@
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" withSubpackages="false" static="false" />
<package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
<package name="tornadofx" withSubpackages="false" static="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="tornadofx" alias="false" withSubpackages="false" />
</value>
</option>
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />

View File

@ -1,6 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@ -118,7 +118,7 @@ class StandaloneCordaRPClientTest {
val hash = HashingInputStream(Hashing.sha256(), rpcProxy.openAttachment(id)).use { it ->
it.copyTo(NULL_OUTPUT_STREAM)
SecureHash.SHA256(it.hash().asBytes())
SecureHash.createSHA256(it.hash().asBytes())
}
assertEquals(attachment.sha256, hash)
}
@ -133,7 +133,7 @@ class StandaloneCordaRPClientTest {
val hash = HashingInputStream(Hashing.sha256(), rpcProxy.openAttachment(id)).use { it ->
it.copyTo(NULL_OUTPUT_STREAM)
SecureHash.SHA256(it.hash().asBytes())
SecureHash.createSHA256(it.hash().asBytes())
}
assertEquals(attachment.sha256, hash)
}

View File

@ -1,6 +1,7 @@
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 {
@ -77,6 +78,7 @@ def patchCore = tasks.register('patchCore', Zip) {
exclude 'net/corda/core/serialization/internal/AttachmentsHolderImpl.class'
exclude 'net/corda/core/serialization/internal/CheckpointSerializationFactory*.class'
exclude 'net/corda/core/internal/rules/*.class'
exclude 'net/corda/core/internal/utilities/PrivateInterner*.class'
}
reproducibleFileOrder = true

View File

@ -0,0 +1,16 @@
package net.corda.core.internal.utilities
import net.corda.core.KeepForDJVM
@KeepForDJVM
class PrivateInterner<T>(val verifier: IternabilityVerifier<T> = AlwaysInternableVerifier()) {
// DJVM implementation does not intern and does not use Guava
fun <S : T> intern(sample: S): S = sample
@KeepForDJVM
companion object {
@Suppress("UNUSED_PARAMETER")
fun findFor(clazz: Class<*>?): PrivateInterner<Any>? = null
}
}

View File

@ -58,7 +58,7 @@ dependencies {
testCompile "org.assertj:assertj-core:${assertj_version}"
// Guava: Google utilities library.
testCompile "com.google.guava:guava:$guava_version"
compile "com.google.guava:guava:$guava_version"
// For caches rather than guava
compile "com.github.ben-manes.caffeine:caffeine:$caffeine_version"

View File

@ -1,5 +1,6 @@
package net.corda.core.contracts
import net.corda.core.CordaInternal
import net.corda.core.DoNotImplement
import net.corda.core.KeepForDJVM
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint.isSatisfiedBy
@ -7,6 +8,8 @@ import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.isFulfilledBy
import net.corda.core.internal.AttachmentWithContext
import net.corda.core.internal.isUploaderTrusted
import net.corda.core.internal.utilities.Internable
import net.corda.core.internal.utilities.PrivateInterner
import net.corda.core.serialization.CordaSerializable
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.loggerFor
@ -119,7 +122,16 @@ data class SignatureAttachmentConstraint(val key: PublicKey) : AttachmentConstra
return if (!key.isFulfilledBy(attachment.signerKeys.map { it })) {
log.warn("Untrusted signing key: expected $key. but contract attachment contains ${attachment.signerKeys}")
false
}
else true
} else true
}
companion object : Internable<SignatureAttachmentConstraint> {
@CordaInternal
override val interner = PrivateInterner<SignatureAttachmentConstraint>()
/**
* Factory method to be used in preference to the constructor.
*/
fun create(key: PublicKey) = interner.intern(SignatureAttachmentConstraint(key))
}
}

View File

@ -3,7 +3,13 @@ package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.deserialize
import java.io.ByteArrayOutputStream
import java.security.*
import java.security.InvalidAlgorithmParameterException
import java.security.InvalidKeyException
import java.security.PrivateKey
import java.security.Provider
import java.security.PublicKey
import java.security.Signature
import java.security.SignatureException
import java.security.spec.AlgorithmParameterSpec
/**
@ -80,7 +86,7 @@ class CompositeSignature : Signature(SIGNATURE_ALGORITHM) {
fun engineVerify(sigBytes: ByteArray): Boolean {
val sig = sigBytes.deserialize<CompositeSignaturesWithKeys>()
return if (verifyKey.isFulfilledBy(sig.sigs.map { it.by })) {
val clearData = SecureHash.SHA256(buffer.toByteArray())
val clearData = SecureHash.createSHA256(buffer.toByteArray())
sig.sigs.all { it.isValid(clearData) }
} else {
false

View File

@ -5,11 +5,12 @@ import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.crypto.internal.AliasPrivateKey
import net.corda.core.crypto.internal.Instances.withSignature
import net.corda.core.crypto.internal.`id-Curve25519ph`
import net.corda.core.crypto.internal.bouncyCastlePQCProvider
import net.corda.core.crypto.internal.cordaBouncyCastleProvider
import net.corda.core.crypto.internal.cordaSecurityProvider
import net.corda.core.crypto.internal.`id-Curve25519ph`
import net.corda.core.crypto.internal.providerMap
import net.corda.core.internal.utilities.PrivateInterner
import net.corda.core.serialization.serialize
import net.i2p.crypto.eddsa.EdDSAEngine
import net.i2p.crypto.eddsa.EdDSAPrivateKey
@ -710,7 +711,8 @@ object Crypto {
keyPairGenerator.initialize(signatureScheme.algSpec, newSecureRandom())
else
keyPairGenerator.initialize(signatureScheme.keySize!!, newSecureRandom())
return keyPairGenerator.generateKeyPair()
val newKeyPair = keyPairGenerator.generateKeyPair()
return KeyPair(internPublicKey(newKeyPair.public), newKeyPair.private)
}
/**
@ -840,7 +842,7 @@ object Crypto {
val publicKeySpec = ECPublicKeySpec(pointQ, parameterSpec)
val publicKeyD = BCECPublicKey(privateKey.algorithm, publicKeySpec, BouncyCastleProvider.CONFIGURATION)
return KeyPair(publicKeyD, privateKeyD)
return KeyPair(internPublicKey(publicKeyD), privateKeyD)
}
// Deterministically generate an EdDSA key.
@ -853,7 +855,7 @@ object Crypto {
val bytes = macBytes.copyOf(params.curve.field.getb() / 8) // Need to pad the entropy to the valid seed length.
val privateKeyD = EdDSAPrivateKeySpec(bytes, params)
val publicKeyD = EdDSAPublicKeySpec(privateKeyD.a, params)
return KeyPair(EdDSAPublicKey(publicKeyD), EdDSAPrivateKey(privateKeyD))
return KeyPair(internPublicKey(EdDSAPublicKey(publicKeyD)), EdDSAPrivateKey(privateKeyD))
}
/**
@ -892,7 +894,7 @@ object Crypto {
val bytes = entropy.toByteArray().copyOf(params.curve.field.getb() / 8) // Need to pad the entropy to the valid seed length.
val priv = EdDSAPrivateKeySpec(bytes, params)
val pub = EdDSAPublicKeySpec(priv.a, params)
return KeyPair(EdDSAPublicKey(pub), EdDSAPrivateKey(priv))
return KeyPair(internPublicKey(EdDSAPublicKey(pub)), EdDSAPrivateKey(priv))
}
// Custom key pair generator from an entropy required for various tests. It is similar to deriveKeyPairECDSA,
@ -918,7 +920,7 @@ object Crypto {
val publicKeySpec = ECPublicKeySpec(pointQ, parameterSpec)
val pub = BCECPublicKey("EC", publicKeySpec, BouncyCastleProvider.CONFIGURATION)
return KeyPair(pub, priv)
return KeyPair(internPublicKey(pub), priv)
}
// Compute the HMAC-SHA512 using a privateKey as the MAC_key and a seed ByteArray.
@ -990,11 +992,14 @@ object Crypto {
}
}
private val interner = PrivateInterner<PublicKey>()
private fun internPublicKey(key: PublicKey): PublicKey = interner.intern(key)
private fun convertIfBCEdDSAPublicKey(key: PublicKey): PublicKey {
return when (key) {
return internPublicKey(when (key) {
is BCEdDSAPublicKey -> EdDSAPublicKey(X509EncodedKeySpec(key.encoded))
else -> key
}
})
}
private fun convertIfBCEdDSAPrivateKey(key: PrivateKey): PrivateKey {
@ -1026,11 +1031,11 @@ object Crypto {
@JvmStatic
fun toSupportedPublicKey(key: PublicKey): PublicKey {
return when (key) {
is BCECPublicKey -> key
is BCRSAPublicKey -> key
is BCSphincs256PublicKey -> key
is EdDSAPublicKey -> key
is CompositeKey -> key
is BCECPublicKey -> internPublicKey(key)
is BCRSAPublicKey -> internPublicKey(key)
is BCSphincs256PublicKey -> internPublicKey(key)
is EdDSAPublicKey -> internPublicKey(key)
is CompositeKey -> internPublicKey(key)
is BCEdDSAPublicKey -> convertIfBCEdDSAPublicKey(key)
else -> decodePublicKey(key.encoded)
}

View File

@ -3,9 +3,12 @@
package net.corda.core.crypto
import io.netty.util.concurrent.FastThreadLocal
import net.corda.core.CordaInternal
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.crypto.internal.DigestAlgorithmFactory
import net.corda.core.internal.utilities.Internable
import net.corda.core.internal.utilities.PrivateInterner
import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.parseAsHex
@ -66,7 +69,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
}
override fun generate(data: ByteArray): SecureHash {
return HASH(algorithm, digestAs(algorithm, data))
return interner.intern(HASH(algorithm, digestAs(algorithm, data)))
}
}
@ -110,7 +113,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
return if(concatAlgorithm == SHA2_256) {
concatBytes.sha256()
} else {
HASH(concatAlgorithm, digestAs(concatAlgorithm, concatBytes))
interner.intern(HASH(concatAlgorithm, digestAs(concatAlgorithm, concatBytes)))
}
}
@ -121,12 +124,15 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
fun reHash() : SecureHash = hashAs(algorithm, bytes)
// Like static methods in Java, except the 'companion' is a singleton that can have state.
companion object {
companion object : Internable<SecureHash> {
const val SHA2_256 = "SHA-256"
const val SHA2_384 = "SHA-384"
const val SHA2_512 = "SHA-512"
const val DELIMITER = ':'
@CordaInternal
override val interner = PrivateInterner<SecureHash>()
/**
* Converts a SecureHash hash value represented as a {algorithm:}hexadecimal [String] into a [SecureHash].
* @param str An optional algorithm id followed by a delimiter and the sequence of hexadecimal digits that represents a hash value.
@ -157,7 +163,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
val digestLength = digestFor(algorithm).digestLength
val data = value.parseAsHex()
return when (data.size) {
digestLength -> HASH(algorithm, data)
digestLength -> interner.intern(HASH(algorithm, data))
else -> throw IllegalArgumentException("Provided string is ${data.size} bytes not $digestLength bytes in hex: $value")
}
}
@ -171,12 +177,18 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
fun parse(str: String?): SHA256 {
return str?.toUpperCase()?.parseAsHex()?.let {
when (it.size) {
32 -> SHA256(it)
32 -> interner.intern(SHA256(it))
else -> throw IllegalArgumentException("Provided string is ${it.size} bytes not 32 bytes in hex: $str")
}
} ?: throw IllegalArgumentException("Provided string is null")
}
/**
* Factory method for SHA256 to be used in preference to the constructor.
*/
@JvmStatic
fun createSHA256(bytes: ByteArray): SHA256 = interner.intern(SHA256(bytes))
private val messageDigests: ConcurrentMap<String, DigestSupplier> = ConcurrentHashMap()
private fun digestFor(algorithm: String): DigestSupplier {
@ -202,9 +214,9 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
fun hashAs(algorithm: String, bytes: ByteArray): SecureHash {
val hashBytes = digestAs(algorithm, bytes)
return if (algorithm == SHA2_256) {
SHA256(hashBytes)
interner.intern(SHA256(hashBytes))
} else {
HASH(algorithm, hashBytes)
interner.intern(HASH(algorithm, hashBytes))
}
}
@ -222,7 +234,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
} else {
val digest = digestFor(algorithm).get()
val hash = digest.componentDigest(bytes)
HASH(algorithm, hash)
interner.intern(HASH(algorithm, hash))
}
}
@ -240,7 +252,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
} else {
val digest = digestFor(algorithm).get()
val hash = digest.nonceDigest(bytes)
HASH(algorithm, hash)
interner.intern(HASH(algorithm, hash))
}
}
@ -249,7 +261,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
* @param bytes The [ByteArray] to hash.
*/
@JvmStatic
fun sha256(bytes: ByteArray) = SHA256(digestAs(SHA2_256, bytes))
fun sha256(bytes: ByteArray) = interner.intern(SHA256(digestAs(SHA2_256, bytes)))
/**
* Computes the SHA-256 hash of the [ByteArray], and then computes the SHA-256 hash of the hash.
@ -282,7 +294,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
randomSHA256()
} else {
val digest = digestFor(algorithm)
HASH(algorithm, digest.get().digest(secureRandomBytes(digest.digestLength)))
interner.intern(HASH(algorithm, digest.get().digest(secureRandomBytes(digest.digestLength))))
}
}
@ -291,7 +303,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
* This field provides more intuitive access from Java.
*/
@JvmField
val zeroHash: SHA256 = SHA256(ByteArray(32) { 0.toByte() })
val zeroHash: SHA256 = interner.intern(SHA256(ByteArray(32) { 0.toByte() }))
/**
* A SHA-256 hash value consisting of 32 0x00 bytes.
@ -305,7 +317,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
* This field provides more intuitive access from Java.
*/
@JvmField
val allOnesHash: SHA256 = SHA256(ByteArray(32) { 255.toByte() })
val allOnesHash: SHA256 = interner.intern(SHA256(ByteArray(32) { 255.toByte() }))
/**
* A SHA-256 hash value consisting of 32 0xFF bytes.
@ -323,8 +335,8 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
return hashConstants.getOrPut(algorithm) {
val digestLength = digestFor(algorithm).digestLength
HashConstants(
zero = HASH(algorithm, ByteArray(digestLength)),
allOnes = HASH(algorithm, ByteArray(digestLength) { 255.toByte() })
zero = interner.intern(HASH(algorithm, ByteArray(digestLength))),
allOnes = interner.intern(HASH(algorithm, ByteArray(digestLength) { 255.toByte() }))
)
}
}

View File

@ -1,8 +1,12 @@
package net.corda.core.identity
import net.corda.core.CordaInternal
import net.corda.core.DoNotImplement
import net.corda.core.contracts.PartyAndReference
import net.corda.core.flows.Destination
import net.corda.core.internal.utilities.Internable
import net.corda.core.internal.utilities.IternabilityVerifier
import net.corda.core.internal.utilities.PrivateInterner
import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.OpaqueBytes
import java.security.PublicKey
@ -31,4 +35,15 @@ abstract class AbstractParty(val owningKey: PublicKey): Destination {
* ledger.
*/
fun ref(vararg bytes: Byte) = ref(OpaqueBytes.of(*bytes))
@CordaInternal
companion object : Internable<AbstractParty> {
@CordaInternal
override val interner = PrivateInterner<AbstractParty>(object : IternabilityVerifier<AbstractParty> {
override fun choose(original: AbstractParty, interned: AbstractParty): AbstractParty {
// Because Party does not compare name in equals(), don't intern if there's a clash
return if (original.nameOrNull() != interned.nameOrNull()) original else interned
}
})
}
}

View File

@ -22,4 +22,11 @@ class AnonymousParty(owningKey: PublicKey) : Destination, AbstractParty(owningKe
override fun nameOrNull(): CordaX500Name? = null
override fun ref(bytes: OpaqueBytes): PartyAndReference = PartyAndReference(this, bytes)
override fun toString() = "Anonymous(${owningKey.toStringShort()})"
companion object {
/**
* Factory method to be used in preference to the constructor.
*/
fun create(owningKey: PublicKey): AnonymousParty = interner.intern(AnonymousParty(owningKey))
}
}

View File

@ -1,10 +1,13 @@
package net.corda.core.identity
import net.corda.core.CordaInternal
import net.corda.core.KeepForDJVM
import net.corda.core.internal.LegalNameValidator
import net.corda.core.internal.toAttributesMap
import net.corda.core.internal.toX500Name
import net.corda.core.internal.unspecifiedCountry
import net.corda.core.internal.utilities.Internable
import net.corda.core.internal.utilities.PrivateInterner
import net.corda.core.serialization.CordaSerializable
import org.bouncycastle.asn1.x500.style.BCStyle
import java.util.*
@ -68,7 +71,7 @@ data class CordaX500Name(val commonName: String?,
}
}
companion object {
companion object : Internable<CordaX500Name> {
@Deprecated("Not Used")
const val LENGTH_COUNTRY = 2
const val MAX_LENGTH_ORGANISATION = 128
@ -80,6 +83,9 @@ data class CordaX500Name(val commonName: String?,
private val supportedAttributes = setOf(BCStyle.O, BCStyle.C, BCStyle.L, BCStyle.CN, BCStyle.ST, BCStyle.OU)
private val countryCodes: Set<String> = setOf(*Locale.getISOCountries(), unspecifiedCountry)
@CordaInternal
override val interner = PrivateInterner<CordaX500Name>()
@JvmStatic
fun build(principal: X500Principal): CordaX500Name {
val attrsMap = principal.toAttributesMap(supportedAttributes)
@ -89,7 +95,7 @@ data class CordaX500Name(val commonName: String?,
val L = requireNotNull(attrsMap[BCStyle.L]) { "Corda X.500 names must include an L attribute" }
val ST = attrsMap[BCStyle.ST]
val C = requireNotNull(attrsMap[BCStyle.C]) { "Corda X.500 names must include an C attribute" }
return CordaX500Name(CN, OU, O, L, ST, C)
return interner.intern(CordaX500Name(CN, OU, O, L, ST, C))
}
@JvmStatic

View File

@ -45,4 +45,16 @@ class Party(val name: CordaX500Name, owningKey: PublicKey) : Destination, Abstra
override fun ref(bytes: OpaqueBytes): PartyAndReference = PartyAndReference(this, bytes)
override fun toString() = name.toString()
fun description() = "$name (owningKey = ${owningKey.toStringShort()})"
companion object {
/**
* Factory method to be used in preference to the constructor.
*/
fun create(name: CordaX500Name, owningKey: PublicKey): Party = interner.intern(Party(name, owningKey))
/**
* Factory method to be used in preference to the constructor.
*/
fun create(certificate: X509Certificate): Party = interner.intern(Party(certificate))
}
}

View File

@ -6,7 +6,11 @@ import net.corda.core.internal.uncheckedCast
import net.corda.core.internal.validate
import net.corda.core.serialization.CordaSerializable
import java.security.PublicKey
import java.security.cert.*
import java.security.cert.CertPath
import java.security.cert.CertPathValidatorException
import java.security.cert.PKIXCertPathValidatorResult
import java.security.cert.TrustAnchor
import java.security.cert.X509Certificate
/**
* A full party plus the X.509 certificate and path linking the party back to a trust root. Equality of
@ -29,7 +33,7 @@ class PartyAndCertificate(val certPath: CertPath) {
}
@Transient
val party: Party = Party(certificate)
val party: Party = Party.create(certificate)
val owningKey: PublicKey get() = party.owningKey
val name: CordaX500Name get() = party.name

View File

@ -77,7 +77,6 @@ import java.util.stream.StreamSupport
import java.util.zip.Deflater
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import kotlin.collections.LinkedHashSet
import kotlin.math.roundToLong
import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance
@ -165,7 +164,7 @@ fun InputStream.hash(): SecureHash {
}
md.update(buffer, 0, count)
}
SecureHash.SHA256(md.digest())
SecureHash.createSHA256(md.digest())
}
}

View File

@ -0,0 +1,24 @@
package net.corda.core.internal.utilities
import net.corda.core.CordaInternal
import net.corda.core.KeepForDJVM
@KeepForDJVM
interface Internable<T> {
@CordaInternal
val interner: PrivateInterner<T>
}
@KeepForDJVM
@CordaInternal
interface IternabilityVerifier<T> {
// If a type being interned has a slightly dodgy equality check, the more strict rules you probably
// want to apply to interning can be enforced here.
fun choose(original: T, interned: T): T
}
@KeepForDJVM
@CordaInternal
class AlwaysInternableVerifier<T> : IternabilityVerifier<T> {
override fun choose(original: T, interned: T): T = interned
}

View File

@ -0,0 +1,69 @@
package net.corda.core.internal.utilities
import com.google.common.collect.Interners
import net.corda.core.CordaInternal
import net.corda.core.internal.packageNameOrNull
import net.corda.core.internal.uncheckedCast
import net.corda.core.serialization.CordaSerializable
import kotlin.reflect.full.companionObjectInstance
/**
* This class converts instances supplied to [intern] to a common instance within the JVM, amongst all those
* instances that have been submitted. It uses weak references to avoid memory leaks.
*
* NOTE: the Guava interners are Beta, so upgrading Guava may result in us having to adapt this code.
*
* System properties allow disabling, in the event an issue is uncovered in a live environment. The
* correct default for the concurrency setting is the result of performance evaluation.
*/
@CordaInternal
class PrivateInterner<T>(val verifier: IternabilityVerifier<T> = AlwaysInternableVerifier()) {
companion object {
// This value is the default in Guava, and performance testing didn't reveal a need to change
private const val DEFAULT_CONCURRENCY_LEVEL = 4
private val CONCURRENCY_LEVEL = Integer.getInteger("net.corda.core.intern.concurrency", DEFAULT_CONCURRENCY_LEVEL).toInt()
private val DISABLE = java.lang.Boolean.getBoolean("net.corda.core.intern.disable")
/**
* This will look at the companion object of a class, and on the super class companion object,
* to see if they implement [Internable], in which case there is a [PrivateInterner] instance
* available to do interning. Tolerant of null class references and a lack of companion objects.
*/
@Suppress("ComplexMethod")
fun findFor(clazz: Class<*>?): PrivateInterner<Any>? {
fun hasCordaSerializable(type: Class<*>): Boolean {
return type.isAnnotationPresent(CordaSerializable::class.java)
|| type.interfaces.any(::hasCordaSerializable)
|| (type.superclass != null && hasCordaSerializable(type.superclass))
}
fun isSerializableCore(clazz: Class<*>): Boolean {
if (!(clazz.packageNameOrNull?.startsWith("net.corda.core") ?: false)) return false
return hasCordaSerializable(clazz)
}
fun findInterner(clazz: Class<*>?): PrivateInterner<Any>? {
// Kotlin reflection has a habit of throwing exceptions, so protect just in case.
try {
return clazz?.kotlin?.companionObjectInstance?.let {
(it as? Internable<*>)?.let {
uncheckedCast(it.interner)
}
}
} catch (_: Throwable) {
return null
}
}
return if (clazz != null) {
// We try not to ruffle the feathers of kotlin reflection by avoiding throwing all types at it.
if (!isSerializableCore(clazz)) return null
findInterner(clazz) ?: findInterner(clazz.superclass)
} else null
}
}
private val interner = Interners.newBuilder().weak().concurrencyLevel(CONCURRENCY_LEVEL).build<T>()
fun <S : T> intern(sample: S): S = if (DISABLE) sample else uncheckedCast(verifier.choose(sample, interner.intern(sample)))
}

View File

@ -176,7 +176,7 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
Type.ALWAYS_ACCEPT -> ConstraintInfo(AlwaysAcceptAttachmentConstraint)
Type.HASH -> ConstraintInfo(HashAttachmentConstraint(SecureHash.create(data!!.toHexString())))
Type.CZ_WHITELISTED -> ConstraintInfo(WhitelistedByZoneAttachmentConstraint)
Type.SIGNATURE -> ConstraintInfo(SignatureAttachmentConstraint(Crypto.decodePublicKey(data!!)))
Type.SIGNATURE -> ConstraintInfo(SignatureAttachmentConstraint.create(Crypto.decodePublicKey(data!!)))
}
}
}

View File

@ -47,6 +47,9 @@ import java.util.Locale
import java.util.ServiceLoader
import java.util.WeakHashMap
import java.util.function.Function
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set
/**
* A custom ClassLoader that knows how to load classes from a set of attachments. The attachments themselves only
@ -164,7 +167,7 @@ class AttachmentsClassLoader(attachments: List<Attachment>,
if(read <= 0) break
md.update(ctx.buffer, 0, read)
}
return SecureHash.SHA256(md.digest())
return SecureHash.createSHA256(md.digest())
}
private fun isZipOrJar(attachment: Attachment) = attachment.openAsJAR().use { jar ->

View File

@ -650,7 +650,8 @@ open class TransactionBuilder(
}
private fun makeSignatureAttachmentConstraint(attachmentSigners: List<PublicKey>) =
SignatureAttachmentConstraint(CompositeKey.Builder().addKeys(attachmentSigners).build())
SignatureAttachmentConstraint.create(CompositeKey.Builder().addKeys(attachmentSigners)
.build())
private fun getInstalledContractAttachmentId(
contractClassName: String,

View File

@ -1,17 +1,23 @@
package net.corda.nodeapi.internal.serialization.kryo
import com.esotericsoftware.kryo.*
import com.esotericsoftware.kryo.DefaultSerializer
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.KryoException
import com.esotericsoftware.kryo.KryoSerializable
import com.esotericsoftware.kryo.Registration
import com.esotericsoftware.kryo.Serializer
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import com.esotericsoftware.kryo.serializers.FieldSerializer
import com.esotericsoftware.kryo.util.DefaultClassResolver
import com.esotericsoftware.kryo.util.Util
import net.corda.core.internal.kotlinObjectInstance
import net.corda.core.internal.utilities.PrivateInterner
import net.corda.core.internal.writer
import net.corda.core.serialization.internal.CheckpointSerializationContext
import net.corda.core.serialization.ClassWhitelist
import net.corda.core.utilities.contextLogger
import net.corda.core.serialization.internal.AttachmentsClassLoader
import net.corda.core.serialization.internal.CheckpointSerializationContext
import net.corda.core.utilities.contextLogger
import net.corda.serialization.internal.MutableClassWhitelist
import net.corda.serialization.internal.TransientClassWhiteList
import net.corda.serialization.internal.amqp.hasCordaSerializable
@ -19,8 +25,11 @@ import java.io.PrintWriter
import java.lang.reflect.Modifier.isAbstract
import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.Paths
import java.nio.file.StandardOpenOption.*
import java.util.*
import java.nio.file.StandardOpenOption.APPEND
import java.nio.file.StandardOpenOption.CREATE
import java.nio.file.StandardOpenOption.WRITE
import java.util.ArrayList
import java.util.Collections
/**
* Corda specific class resolver which enables extra customisation for the purposes of serialization using Kryo
@ -86,7 +95,7 @@ class CordaClassResolver(serializationContext: CheckpointSerializationContext) :
kotlin.jvm.internal.Lambda::class.java.isAssignableFrom(targetType) -> // Kotlin lambdas extend this class and any captured variables are stored in synthetic fields
FieldSerializer<Any>(kryo, targetType).apply { setIgnoreSyntheticFields(false) }
Throwable::class.java.isAssignableFrom(targetType) -> ThrowableSerializer(kryo, targetType)
else -> kryo.getDefaultSerializer(targetType)
else -> maybeWrapForInterning(kryo.getDefaultSerializer(targetType), targetType)
}
return register(Registration(targetType, serializer, NAME.toInt()))
} finally {
@ -94,6 +103,11 @@ class CordaClassResolver(serializationContext: CheckpointSerializationContext) :
}
}
private fun maybeWrapForInterning(serializer: Serializer<Any>, targetType: Class<*>): Serializer<Any> {
val interner = PrivateInterner.findFor(targetType)
return if (interner != null) InterningSerializer(serializer, interner) else serializer
}
override fun writeName(output: Output, type: Class<*>, registration: Registration) {
super.writeName(output, registration.type ?: type, registration)
}
@ -104,6 +118,11 @@ class CordaClassResolver(serializationContext: CheckpointSerializationContext) :
override fun write(kryo: Kryo, output: Output, obj: Any) = Unit
}
private class InterningSerializer(private val delegate: Serializer<Any>, private val interner: PrivateInterner<Any>) : Serializer<Any>() {
override fun read(kryo: Kryo, input: Input, type: Class<Any>): Any = interner.intern(delegate.read(kryo, input, type))
override fun write(kryo: Kryo, output: Output, obj: Any) = delegate.write(kryo, output, obj)
}
// We don't allow the annotation for classes in attachments for now. The class will be on the main classpath if we have the CorDapp installed.
// We also do not allow extension of KryoSerializable for annotated classes, or combination with @DefaultSerializer for custom serialisation.
// TODO: Later we can support annotations on attachment classes and spin up a proxy via bytecode that we know is harmless.

View File

@ -59,9 +59,8 @@ import java.security.PrivateKey
import java.security.PublicKey
import java.security.cert.CertPath
import java.security.cert.X509Certificate
import java.util.Arrays
import java.util.BitSet
import java.util.ServiceLoader
import java.util.*
import kotlin.collections.ArrayList
object DefaultKryoCustomizer {
private val serializationWhitelists: List<SerializationWhitelist> by lazy {
@ -233,7 +232,7 @@ object DefaultKryoCustomizer {
@Suppress("UNCHECKED_CAST")
override fun read(kryo: Kryo, input: Input, type: Class<ContractAttachment>): ContractAttachment {
if (kryo.serializationContext() != null) {
val attachmentHash = SecureHash.SHA256(input.readBytes(32))
val attachmentHash = SecureHash.createSHA256(input.readBytes(32))
val contract = input.readString()
val additionalContracts = kryo.readClassAndObject(input) as Set<ContractClassName>
val uploader = input.readString()

View File

@ -9,22 +9,38 @@ import com.google.common.primitives.Ints
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.contracts.PrivacySalt
import net.corda.core.crypto.*
import net.corda.core.contracts.SignatureAttachmentConstraint
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.SignableData
import net.corda.core.crypto.SignatureMetadata
import net.corda.core.crypto.generateKeyPair
import net.corda.core.crypto.sha256
import net.corda.core.crypto.sign
import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.internal.FetchDataFlow
import net.corda.core.serialization.*
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.EncodingWhitelist
import net.corda.core.serialization.internal.CheckpointSerializationContext
import net.corda.core.serialization.internal.checkpointDeserialize
import net.corda.core.serialization.internal.checkpointSerialize
import net.corda.core.utilities.ByteSequence
import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.sequence
import net.corda.serialization.internal.*
import net.corda.coretesting.internal.rigorousMock
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.CheckpointSerializationContextImpl
import net.corda.serialization.internal.CordaSerializationEncoding
import net.corda.serialization.internal.encodingNotPermittedFormat
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.TestIdentity
import net.corda.testing.core.internal.CheckpointSerializationEnvironmentRule
import net.corda.coretesting.internal.rigorousMock
import org.apache.commons.lang3.SystemUtils
import org.assertj.core.api.Assertions.*
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.assertj.core.api.Assertions.catchThrowable
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Before
@ -36,9 +52,13 @@ import org.junit.runners.Parameterized.Parameters
import org.slf4j.LoggerFactory
import java.io.InputStream
import java.time.Instant
import java.util.*
import kotlin.collections.ArrayList
import kotlin.test.*
import java.util.Collections
import java.util.Random
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotNull
import kotlin.test.assertSame
import kotlin.test.assertTrue
@RunWith(Parameterized::class)
class KryoTests(private val compression: CordaSerializationEncoding?) {
@ -129,6 +149,7 @@ class KryoTests(private val compression: CordaSerializationEncoding?) {
val deserialisedSignature = deserialisedKeyPair.sign(bitsToSign)
deserialisedSignature.verify(bitsToSign)
assertThatThrownBy { deserialisedSignature.verify(wrongBits) }
assertSame(keyPair.public, deserialisedKeyPair.public)
}
@Test(timeout=300_000)
@ -178,7 +199,7 @@ class KryoTests(private val compression: CordaSerializationEncoding?) {
}
@Test(timeout=300_000)
fun `serialize - deserialize SignableData`() {
fun `serialize - deserialize SignableData`() {
val testString = "Hello World"
val testBytes = testString.toByteArray()
@ -186,15 +207,33 @@ class KryoTests(private val compression: CordaSerializationEncoding?) {
val serializedMetaData = meta.checkpointSerialize(context).bytes
val meta2 = serializedMetaData.checkpointDeserialize<SignableData>(context)
assertEquals(meta2, meta)
assertSame(meta.txId, meta2.txId)
}
@Test(timeout=300_000)
fun `serialize - deserialize Logger`() {
@Test(timeout = 300_000)
fun `serialize - deserialize internables`() {
val list: List<Any> = listOf(
SecureHash.randomSHA256(),
CordaX500Name.parse("O=bank A, L=New York, C=DE, OU=Org Unit, CN=Service Name"),
Party.create(CordaX500Name.parse("O=bank A, L=New York, C=DE, OU=Org Unit, CN=Service Name"), Crypto.generateKeyPair().public),
AnonymousParty.create(Crypto.generateKeyPair().public),
SignatureAttachmentConstraint.create(Crypto.generateKeyPair().public)
)
val serializedList = list.checkpointSerialize(context).bytes
val list2 = serializedList.checkpointDeserialize<List<Any>>(context)
list.zip(list2).forEach { (original, deserialized) ->
assertSame(original, deserialized, "${original.javaClass} not interned")
}
}
@Test(timeout = 300_000)
fun `serialize - deserialize Logger`() {
val storageContext: CheckpointSerializationContext = context
val logger = LoggerFactory.getLogger("aName")
val logger2 = logger.checkpointSerialize(storageContext).checkpointDeserialize(storageContext)
assertEquals(logger.name, logger2.name)
assertTrue(logger === logger2)
assertSame(logger, logger2)
}
@CordaSerializable

View File

@ -12,10 +12,21 @@ import net.corda.core.contracts.ContractAttachment
import net.corda.core.contracts.ContractClassName
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.sha256
import net.corda.core.internal.*
import net.corda.core.internal.AbstractAttachment
import net.corda.core.internal.DEPLOYED_CORDAPP_UPLOADER
import net.corda.core.internal.FetchAttachmentsFlow
import net.corda.core.internal.JarSignatureCollector
import net.corda.core.internal.NamedCacheFactory
import net.corda.core.internal.P2P_UPLOADER
import net.corda.core.internal.RPC_UPLOADER
import net.corda.core.internal.TRUSTED_UPLOADERS
import net.corda.core.internal.UNKNOWN_UPLOADER
import net.corda.core.internal.Version
import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.cordapp.CordappImpl.Companion.CORDAPP_CONTRACT_VERSION
import net.corda.core.internal.cordapp.CordappImpl.Companion.DEFAULT_CORDAPP_VERSION
import net.corda.core.internal.isUploaderTrusted
import net.corda.core.internal.readFully
import net.corda.core.internal.utilities.ZipBombDetector
import net.corda.core.node.ServicesForResolution
import net.corda.core.node.services.AttachmentId
@ -23,7 +34,11 @@ import net.corda.core.node.services.vault.AttachmentQueryCriteria
import net.corda.core.node.services.vault.AttachmentSort
import net.corda.core.node.services.vault.Builder
import net.corda.core.node.services.vault.Sort
import net.corda.core.serialization.*
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializationToken
import net.corda.core.serialization.SerializeAsToken
import net.corda.core.serialization.SerializeAsTokenContext
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.utilities.contextLogger
import net.corda.node.services.vault.HibernateAttachmentQueryCriteriaParser
import net.corda.node.utilities.InfrequentlyMutatedCache
@ -46,7 +61,17 @@ import java.util.jar.JarEntry
import java.util.jar.JarInputStream
import java.util.stream.Stream
import javax.annotation.concurrent.ThreadSafe
import javax.persistence.*
import javax.persistence.CollectionTable
import javax.persistence.Column
import javax.persistence.ElementCollection
import javax.persistence.Entity
import javax.persistence.FetchType
import javax.persistence.ForeignKey
import javax.persistence.Id
import javax.persistence.Index
import javax.persistence.JoinColumn
import javax.persistence.Lob
import javax.persistence.Table
/**
* Stores attachments using Hibernate to database.
@ -211,7 +236,7 @@ class NodeAttachmentService @JvmOverloads constructor(
private fun validate() {
if (counter.count != expectedSize.toLong()) return
val actual = SecureHash.SHA256(hash.asBytes())
val actual = SecureHash.createSHA256(hash.asBytes())
if (actual != expected)
throw HashMismatchException(expected, actual)
}

View File

@ -12,6 +12,7 @@ import org.junit.Assert.assertArrayEquals
import org.junit.Rule
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertSame
import kotlin.test.assertTrue
class SecureHashSerializationTest {
@ -29,6 +30,7 @@ class SecureHashSerializationTest {
assertEquals(before.algorithm, after.algorithm)
assertEquals(after.algorithm, SHA2_256)
assertTrue(after is SecureHash.SHA256)
assertSame(before, after)
}
@Test(timeout = 300_000)
@ -41,5 +43,6 @@ class SecureHashSerializationTest {
assertEquals(before.algorithm, after.algorithm)
assertEquals(after.algorithm, SHA2_512)
assertTrue(after is SecureHash.HASH)
assertSame(before, after)
}
}

View File

@ -0,0 +1,24 @@
package net.corda.serialization.internal.amqp
import net.corda.core.internal.utilities.PrivateInterner
import net.corda.core.serialization.SerializationContext
import org.apache.qpid.proton.codec.Data
import java.lang.reflect.Type
class InterningSerializer(private val delegate: ObjectSerializer, private val interner: PrivateInterner<Any>) : ObjectSerializer by delegate {
companion object {
fun maybeWrapForInterning(candidate: ObjectSerializer): ObjectSerializer {
val clazz = candidate.type as? Class<*>
val interner: PrivateInterner<Any>? = PrivateInterner.findFor(clazz)
return if (interner != null) InterningSerializer(candidate, interner) else candidate
}
}
override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput, context: SerializationContext, debugIndent: Int) {
delegate.writeObject(obj, data, type, output, context, debugIndent)
}
override fun readObject(obj: Any, schemas: SerializationSchemas, input: DeserializationInput, context: SerializationContext): Any {
return interner.intern(delegate.readObject(obj, schemas, input, context))
}
}

View File

@ -71,7 +71,7 @@ interface ObjectSerializer : AMQPSerializer<Any> {
private fun makeForComposable(typeInformation: LocalTypeInformation.Composable,
typeNotation: CompositeType,
typeDescriptor: Symbol,
factory: LocalSerializerFactory): ComposableObjectSerializer {
factory: LocalSerializerFactory): ObjectSerializer {
val propertySerializers = makePropertySerializers(typeInformation.properties, factory)
val reader = ComposableObjectReader(
typeInformation.typeIdentifier,
@ -83,13 +83,13 @@ interface ObjectSerializer : AMQPSerializer<Any> {
typeInformation.interfaces,
propertySerializers)
return ComposableObjectSerializer(
return InterningSerializer.maybeWrapForInterning(ComposableObjectSerializer(
typeInformation.observedType,
typeDescriptor,
propertySerializers,
typeNotation.fields,
reader,
writer)
writer))
}
private fun makePropertySerializers(properties: Map<PropertyName, LocalPropertyInformation>,

View File

@ -1,6 +1,7 @@
package net.corda.serialization.internal.amqp
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.SignatureAttachmentConstraint
import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TransactionState
@ -20,6 +21,8 @@ import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test
import java.math.BigInteger
import kotlin.test.assertEquals
import kotlin.test.assertNotSame
import kotlin.test.assertSame
class RoundTripTests {
@ -145,6 +148,42 @@ class RoundTripTests {
fun canSerializeClassesWithUntypedProperties() {
val data = MembershipState<Any>(mapOf("foo" to "bar"))
val party = Party(
CordaX500Name.interner.intern(CordaX500Name(organisation = "Test Corp", locality = "Madrid", country = "ES")),
entropyToKeyPair(BigInteger.valueOf(83)).public)
val transactionState = TransactionState(
data,
"foo",
party
)
val ref = StateRef(SecureHash.zeroHash, 0)
val instance = OnMembershipChanged(StateAndRef(
transactionState,
ref
))
val factory = testDefaultFactoryNoEvolution().apply { register(PublicKeySerializer) }
val bytes = SerializationOutput(factory).serialize(instance)
val deserialized = DeserializationInput(factory).deserialize(bytes)
assertEquals(mapOf("foo" to "bar"), deserialized.changedMembership.state.data.metadata)
assertNotSame(instance.changedMembership.state.notary, deserialized.changedMembership.state.notary)
assertSame(instance.changedMembership.state.notary.name, deserialized.changedMembership.state.notary.name)
assertSame(instance.changedMembership.state.notary.owningKey, deserialized.changedMembership.state.notary.owningKey)
}
@Test(timeout = 300_000)
fun sigConstraintsInterned() {
val instance = SignatureAttachmentConstraint.create(entropyToKeyPair(BigInteger.valueOf(83)).public)
val factory = testDefaultFactoryNoEvolution().apply { register(PublicKeySerializer) }
val bytes = SerializationOutput(factory).serialize(instance)
val deserialized = DeserializationInput(factory).deserialize(bytes)
assertSame(instance, deserialized)
}
@Test(timeout = 300_000)
fun canSerializeClassesWithUntypedPropertiesWithInternedParty() {
val data = MembershipState<Any>(mapOf("foo" to "bar"))
val party = Party.create(
CordaX500Name(organisation = "Test Corp", locality = "Madrid", country = "ES"),
entropyToKeyPair(BigInteger.valueOf(83)).public)
val transactionState = TransactionState(
@ -162,6 +201,7 @@ class RoundTripTests {
val bytes = SerializationOutput(factory).serialize(instance)
val deserialized = DeserializationInput(factory).deserialize(bytes)
assertEquals(mapOf("foo" to "bar"), deserialized.changedMembership.state.data.metadata)
assertSame(instance.changedMembership.state.notary, deserialized.changedMembership.state.notary)
}
interface I2<T> {
@ -170,8 +210,8 @@ class RoundTripTests {
data class C<A, B : A>(override val t: B) : I2<B>
@Test(timeout=300_000)
fun recursiveTypeVariableResolution() {
@Test(timeout = 300_000)
fun recursiveTypeVariableResolution() {
val factory = testDefaultFactoryNoEvolution()
val instance = C<Collection<String>, List<String>>(emptyList())