Merge branch 'release/os/4.11' into merge-release/os/4.10-release/os/4.11-2023-10-17-7

This commit is contained in:
Rick Parker 2023-10-17 11:03:02 +01:00 committed by GitHub
commit 0befdd6ebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
585 changed files with 6792 additions and 13871 deletions

View File

@ -1798,6 +1798,8 @@ public final class net.corda.core.crypto.Crypto extends java.lang.Object
public static final boolean doVerify(net.corda.core.crypto.SecureHash, net.corda.core.crypto.TransactionSignature) public static final boolean doVerify(net.corda.core.crypto.SecureHash, net.corda.core.crypto.TransactionSignature)
public static final boolean doVerify(net.corda.core.crypto.SignatureScheme, java.security.PublicKey, byte[], byte[]) public static final boolean doVerify(net.corda.core.crypto.SignatureScheme, java.security.PublicKey, byte[], byte[])
@NotNull @NotNull
public static final byte[] encodePublicKey(java.security.PublicKey)
@NotNull
public static final java.security.Provider findProvider(String) public static final java.security.Provider findProvider(String)
@NotNull @NotNull
public static final net.corda.core.crypto.SignatureScheme findSignatureScheme(int) public static final net.corda.core.crypto.SignatureScheme findSignatureScheme(int)
@ -2518,12 +2520,16 @@ public static final class net.corda.core.flows.ContractUpgradeFlow$Initiate exte
protected net.corda.core.flows.AbstractStateReplacementFlow$UpgradeTx assembleTx() protected net.corda.core.flows.AbstractStateReplacementFlow$UpgradeTx assembleTx()
## ##
public class net.corda.core.flows.DataVendingFlow extends net.corda.core.flows.FlowLogic public class net.corda.core.flows.DataVendingFlow extends net.corda.core.flows.FlowLogic
public <init>(java.util.Set<? extends net.corda.core.flows.FlowSession>, Object, net.corda.core.flows.TransactionMetadata)
public <init>(java.util.Set, Object, net.corda.core.flows.TransactionMetadata, int, kotlin.jvm.internal.DefaultConstructorMarker)
public <init>(net.corda.core.flows.FlowSession, Object) public <init>(net.corda.core.flows.FlowSession, Object)
public <init>(net.corda.core.flows.FlowSession, Object, net.corda.core.flows.TransactionMetadata)
public <init>(net.corda.core.flows.FlowSession, Object, net.corda.core.flows.TransactionMetadata, int, kotlin.jvm.internal.DefaultConstructorMarker)
@Suspendable @Suspendable
@Nullable @Nullable
public Void call() public Void call()
@NotNull @NotNull
public final net.corda.core.flows.FlowSession getOtherSideSession() public final java.util.Set<net.corda.core.flows.FlowSession> getOtherSessions()
@NotNull @NotNull
public final Object getPayload() public final Object getPayload()
@Suspendable @Suspendable
@ -2535,10 +2541,61 @@ public class net.corda.core.flows.DataVendingFlow extends net.corda.core.flows.F
@DoNotImplement @DoNotImplement
public interface net.corda.core.flows.Destination public interface net.corda.core.flows.Destination
## ##
@CordaSerializable
public abstract class net.corda.core.flows.DistributionList extends java.lang.Object
public <init>(kotlin.jvm.internal.DefaultConstructorMarker)
##
@CordaSerializable
public static final class net.corda.core.flows.DistributionList$ReceiverDistributionList extends net.corda.core.flows.DistributionList
public <init>(byte[], net.corda.core.node.StatesToRecord)
@NotNull
public final byte[] component1()
@NotNull
public final net.corda.core.node.StatesToRecord component2()
@NotNull
public final net.corda.core.flows.DistributionList$ReceiverDistributionList copy(byte[], net.corda.core.node.StatesToRecord)
public boolean equals(Object)
@NotNull
public final byte[] getOpaqueData()
@NotNull
public final net.corda.core.node.StatesToRecord getReceiverStatesToRecord()
public int hashCode()
@NotNull
public String toString()
##
@CordaSerializable
public static final class net.corda.core.flows.DistributionList$SenderDistributionList extends net.corda.core.flows.DistributionList
public <init>(net.corda.core.node.StatesToRecord, java.util.Map<net.corda.core.identity.CordaX500Name, ? extends net.corda.core.node.StatesToRecord>)
@NotNull
public final net.corda.core.node.StatesToRecord component1()
@NotNull
public final java.util.Map<net.corda.core.identity.CordaX500Name, net.corda.core.node.StatesToRecord> component2()
@NotNull
public final net.corda.core.flows.DistributionList$SenderDistributionList copy(net.corda.core.node.StatesToRecord, java.util.Map<net.corda.core.identity.CordaX500Name, ? extends net.corda.core.node.StatesToRecord>)
public boolean equals(Object)
@NotNull
public final java.util.Map<net.corda.core.identity.CordaX500Name, net.corda.core.node.StatesToRecord> getPeersToStatesToRecord()
@NotNull
public final net.corda.core.node.StatesToRecord getSenderStatesToRecord()
public int hashCode()
@NotNull
public String toString()
@CordaSerializable
public abstract class net.corda.core.flows.DistributionRecord extends java.lang.Object implements net.corda.core.contracts.NamedByHash
public <init>()
@NotNull
public abstract net.corda.core.crypto.SecureHash getPeerPartyId()
@NotNull
public abstract java.time.Instant getTimestamp()
public abstract int getTimestampDiscriminator()
@NotNull
public abstract net.corda.core.crypto.SecureHash getTxId()
##
@InitiatingFlow @InitiatingFlow
public final class net.corda.core.flows.FinalityFlow extends net.corda.core.flows.FlowLogic public final class net.corda.core.flows.FinalityFlow extends net.corda.core.flows.FlowLogic
public <init>(net.corda.core.transactions.SignedTransaction) public <init>(net.corda.core.transactions.SignedTransaction)
public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>) public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>)
public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, java.util.Collection<? extends net.corda.core.flows.FlowSession>)
public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, java.util.Collection<net.corda.core.identity.Party>, net.corda.core.utilities.ProgressTracker) public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, java.util.Collection<net.corda.core.identity.Party>, net.corda.core.utilities.ProgressTracker)
public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, net.corda.core.node.StatesToRecord) public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, net.corda.core.node.StatesToRecord)
public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, net.corda.core.node.StatesToRecord, net.corda.core.utilities.ProgressTracker) public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, net.corda.core.node.StatesToRecord, net.corda.core.utilities.ProgressTracker)
@ -2570,12 +2627,32 @@ public static final class net.corda.core.flows.FinalityFlow$Companion$BROADCASTI
public static final net.corda.core.flows.FinalityFlow$Companion$BROADCASTING INSTANCE public static final net.corda.core.flows.FinalityFlow$Companion$BROADCASTING INSTANCE
## ##
@CordaSerializable @CordaSerializable
public static final class net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_NOTARY_ERROR extends net.corda.core.utilities.ProgressTracker$Step
public static final net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_NOTARY_ERROR INSTANCE
##
@CordaSerializable
public static final class net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_POST_NOTARISATION extends net.corda.core.utilities.ProgressTracker$Step
public static final net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_POST_NOTARISATION INSTANCE
##
@CordaSerializable
public static final class net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_PRE_NOTARISATION extends net.corda.core.utilities.ProgressTracker$Step
public static final net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_PRE_NOTARISATION INSTANCE
##
@CordaSerializable
public static final class net.corda.core.flows.FinalityFlow$Companion$FINALISING_TRANSACTION extends net.corda.core.utilities.ProgressTracker$Step
public static final net.corda.core.flows.FinalityFlow$Companion$FINALISING_TRANSACTION INSTANCE
##
@CordaSerializable
public static final class net.corda.core.flows.FinalityFlow$Companion$NOTARISING extends net.corda.core.utilities.ProgressTracker$Step public static final class net.corda.core.flows.FinalityFlow$Companion$NOTARISING extends net.corda.core.utilities.ProgressTracker$Step
@NotNull @NotNull
public net.corda.core.utilities.ProgressTracker childProgressTracker() public net.corda.core.utilities.ProgressTracker childProgressTracker()
public static final net.corda.core.flows.FinalityFlow$Companion$NOTARISING INSTANCE public static final net.corda.core.flows.FinalityFlow$Companion$NOTARISING INSTANCE
## ##
@CordaSerializable @CordaSerializable
public static final class net.corda.core.flows.FinalityFlow$Companion$RECORD_UNNOTARISED extends net.corda.core.utilities.ProgressTracker$Step
public static final net.corda.core.flows.FinalityFlow$Companion$RECORD_UNNOTARISED INSTANCE
##
@CordaSerializable
public class net.corda.core.flows.FlowException extends net.corda.core.CordaException implements net.corda.core.flows.IdentifiableException public class net.corda.core.flows.FlowException extends net.corda.core.CordaException implements net.corda.core.flows.IdentifiableException
public <init>() public <init>()
public <init>(String) public <init>(String)
@ -2877,6 +2954,37 @@ public static final class net.corda.core.flows.FlowStackSnapshot$Frame extends j
public String toString() public String toString()
## ##
@CordaSerializable @CordaSerializable
public final class net.corda.core.flows.FlowTransactionInfo extends java.lang.Object
public <init>(net.corda.core.flows.StateMachineRunId, String, net.corda.core.flows.TransactionStatus, java.time.Instant, net.corda.core.flows.TransactionMetadata)
@NotNull
public final net.corda.core.flows.StateMachineRunId component1()
@NotNull
public final String component2()
@NotNull
public final net.corda.core.flows.TransactionStatus component3()
@NotNull
public final java.time.Instant component4()
@Nullable
public final net.corda.core.flows.TransactionMetadata component5()
@NotNull
public final net.corda.core.flows.FlowTransactionInfo copy(net.corda.core.flows.StateMachineRunId, String, net.corda.core.flows.TransactionStatus, java.time.Instant, net.corda.core.flows.TransactionMetadata)
public boolean equals(Object)
@Nullable
public final net.corda.core.flows.TransactionMetadata getMetadata()
@NotNull
public final net.corda.core.flows.StateMachineRunId getStateMachineRunId()
@NotNull
public final net.corda.core.flows.TransactionStatus getStatus()
@NotNull
public final java.time.Instant getTimestamp()
@NotNull
public final String getTxId()
public int hashCode()
public final boolean isInitiator(net.corda.core.identity.CordaX500Name)
@NotNull
public String toString()
##
@CordaSerializable
public class net.corda.core.flows.HospitalizeFlowException extends net.corda.core.CordaRuntimeException public class net.corda.core.flows.HospitalizeFlowException extends net.corda.core.CordaRuntimeException
public <init>() public <init>()
public <init>(String) public <init>(String)
@ -3138,6 +3246,10 @@ public static final class net.corda.core.flows.NotaryFlow$Client$Companion$REQUE
public static final class net.corda.core.flows.NotaryFlow$Client$Companion$VALIDATING extends net.corda.core.utilities.ProgressTracker$Step public static final class net.corda.core.flows.NotaryFlow$Client$Companion$VALIDATING extends net.corda.core.utilities.ProgressTracker$Step
public static final net.corda.core.flows.NotaryFlow$Client$Companion$VALIDATING INSTANCE public static final net.corda.core.flows.NotaryFlow$Client$Companion$VALIDATING INSTANCE
## ##
public final class net.corda.core.flows.NotarySigCheck extends java.lang.Object
public final boolean needsNotarySignature(net.corda.core.transactions.SignedTransaction)
public static final net.corda.core.flows.NotarySigCheck INSTANCE
##
public final class net.corda.core.flows.ReceiveFinalityFlow extends net.corda.core.flows.FlowLogic public final class net.corda.core.flows.ReceiveFinalityFlow extends net.corda.core.flows.FlowLogic
public <init>(net.corda.core.flows.FlowSession) public <init>(net.corda.core.flows.FlowSession)
public <init>(net.corda.core.flows.FlowSession, net.corda.core.crypto.SecureHash) public <init>(net.corda.core.flows.FlowSession, net.corda.core.crypto.SecureHash)
@ -3165,6 +3277,41 @@ public class net.corda.core.flows.ReceiveTransactionFlow extends net.corda.core.
protected void checkBeforeRecording(net.corda.core.transactions.SignedTransaction) protected void checkBeforeRecording(net.corda.core.transactions.SignedTransaction)
## ##
@CordaSerializable @CordaSerializable
public final class net.corda.core.flows.RecoveryTimeWindow extends java.lang.Object
public <init>(java.time.Instant, java.time.Instant)
public <init>(java.time.Instant, java.time.Instant, int, kotlin.jvm.internal.DefaultConstructorMarker)
@NotNull
public static final net.corda.core.flows.RecoveryTimeWindow between(java.time.Instant, java.time.Instant)
@NotNull
public final java.time.Instant component1()
@NotNull
public final java.time.Instant component2()
@NotNull
public final net.corda.core.flows.RecoveryTimeWindow copy(java.time.Instant, java.time.Instant)
public boolean equals(Object)
@NotNull
public static final net.corda.core.flows.RecoveryTimeWindow fromOnly(java.time.Instant)
@NotNull
public final java.time.Instant getFromTime()
@NotNull
public final java.time.Instant getUntilTime()
public int hashCode()
@NotNull
public String toString()
@NotNull
public static final net.corda.core.flows.RecoveryTimeWindow untilOnly(java.time.Instant)
public static final net.corda.core.flows.RecoveryTimeWindow$Companion Companion
##
public static final class net.corda.core.flows.RecoveryTimeWindow$Companion extends java.lang.Object
public <init>(kotlin.jvm.internal.DefaultConstructorMarker)
@NotNull
public final net.corda.core.flows.RecoveryTimeWindow between(java.time.Instant, java.time.Instant)
@NotNull
public final net.corda.core.flows.RecoveryTimeWindow fromOnly(java.time.Instant)
@NotNull
public final net.corda.core.flows.RecoveryTimeWindow untilOnly(java.time.Instant)
##
@CordaSerializable
public final class net.corda.core.flows.ResultSerializationException extends net.corda.core.CordaRuntimeException public final class net.corda.core.flows.ResultSerializationException extends net.corda.core.CordaRuntimeException
public <init>(net.corda.core.serialization.internal.MissingSerializerException) public <init>(net.corda.core.serialization.internal.MissingSerializerException)
## ##
@ -3175,6 +3322,12 @@ public class net.corda.core.flows.SendStateAndRefFlow extends net.corda.core.flo
## ##
public class net.corda.core.flows.SendTransactionFlow extends net.corda.core.flows.DataVendingFlow public class net.corda.core.flows.SendTransactionFlow extends net.corda.core.flows.DataVendingFlow
public <init>(net.corda.core.flows.FlowSession, net.corda.core.transactions.SignedTransaction) public <init>(net.corda.core.flows.FlowSession, net.corda.core.transactions.SignedTransaction)
public static final net.corda.core.flows.SendTransactionFlow$Companion Companion
##
public static final class net.corda.core.flows.SendTransactionFlow$Companion extends java.lang.Object
public <init>(kotlin.jvm.internal.DefaultConstructorMarker)
@NotNull
public final net.corda.core.identity.CordaX500Name getDUMMY_PARTICIPANT_NAME()
## ##
public abstract class net.corda.core.flows.SignTransactionFlow extends net.corda.core.flows.FlowLogic public abstract class net.corda.core.flows.SignTransactionFlow extends net.corda.core.flows.FlowLogic
public <init>(net.corda.core.flows.FlowSession) public <init>(net.corda.core.flows.FlowSession)
@ -3282,6 +3435,29 @@ public class net.corda.core.flows.StateReplacementException extends net.corda.co
public <init>(String, Throwable, int, kotlin.jvm.internal.DefaultConstructorMarker) public <init>(String, Throwable, int, kotlin.jvm.internal.DefaultConstructorMarker)
## ##
@CordaSerializable @CordaSerializable
public final class net.corda.core.flows.TransactionMetadata extends java.lang.Object
public <init>(net.corda.core.identity.CordaX500Name, net.corda.core.flows.DistributionList)
@NotNull
public final net.corda.core.identity.CordaX500Name component1()
@NotNull
public final net.corda.core.flows.DistributionList component2()
@NotNull
public final net.corda.core.flows.TransactionMetadata copy(net.corda.core.identity.CordaX500Name, net.corda.core.flows.DistributionList)
public boolean equals(Object)
@NotNull
public final net.corda.core.flows.DistributionList getDistributionList()
@NotNull
public final net.corda.core.identity.CordaX500Name getInitiator()
public int hashCode()
@NotNull
public String toString()
##
@CordaSerializable
public final class net.corda.core.flows.TransactionStatus extends java.lang.Enum
public static net.corda.core.flows.TransactionStatus valueOf(String)
public static net.corda.core.flows.TransactionStatus[] values()
##
@CordaSerializable
public final class net.corda.core.flows.UnexpectedFlowEndException extends net.corda.core.CordaRuntimeException implements net.corda.core.flows.IdentifiableException public final class net.corda.core.flows.UnexpectedFlowEndException extends net.corda.core.CordaRuntimeException implements net.corda.core.flows.IdentifiableException
public <init>(String) public <init>(String)
public <init>(String, Throwable) public <init>(String, Throwable)
@ -4141,6 +4317,7 @@ public interface net.corda.core.node.ServicesForResolution
@NotNull @NotNull
public net.corda.core.transactions.LedgerTransaction specialise(net.corda.core.transactions.LedgerTransaction) public net.corda.core.transactions.LedgerTransaction specialise(net.corda.core.transactions.LedgerTransaction)
## ##
@CordaSerializable
public final class net.corda.core.node.StatesToRecord extends java.lang.Enum public final class net.corda.core.node.StatesToRecord extends java.lang.Enum
public static net.corda.core.node.StatesToRecord valueOf(String) public static net.corda.core.node.StatesToRecord valueOf(String)
public static net.corda.core.node.StatesToRecord[] values() public static net.corda.core.node.StatesToRecord[] values()
@ -4474,6 +4651,8 @@ public static final class net.corda.core.node.services.Vault$ConstraintInfo$Type
@CordaSerializable @CordaSerializable
public static final class net.corda.core.node.services.Vault$Page extends java.lang.Object public static final class net.corda.core.node.services.Vault$Page extends java.lang.Object
public <init>(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends T>>, java.util.List<net.corda.core.node.services.Vault$StateMetadata>, long, net.corda.core.node.services.Vault$StateStatus, java.util.List<?>) public <init>(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends T>>, java.util.List<net.corda.core.node.services.Vault$StateMetadata>, long, net.corda.core.node.services.Vault$StateStatus, java.util.List<?>)
public <init>(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends T>>, java.util.List<net.corda.core.node.services.Vault$StateMetadata>, long, net.corda.core.node.services.Vault$StateStatus, java.util.List<?>, net.corda.core.contracts.StateRef)
public <init>(java.util.List, java.util.List, long, net.corda.core.node.services.Vault$StateStatus, java.util.List, net.corda.core.contracts.StateRef, int, kotlin.jvm.internal.DefaultConstructorMarker)
@NotNull @NotNull
public final java.util.List<net.corda.core.contracts.StateAndRef<T>> component1() public final java.util.List<net.corda.core.contracts.StateAndRef<T>> component1()
@NotNull @NotNull
@ -4483,11 +4662,17 @@ public static final class net.corda.core.node.services.Vault$Page extends java.l
public final net.corda.core.node.services.Vault$StateStatus component4() public final net.corda.core.node.services.Vault$StateStatus component4()
@NotNull @NotNull
public final java.util.List<Object> component5() public final java.util.List<Object> component5()
@Nullable
public final net.corda.core.contracts.StateRef component6()
@NotNull @NotNull
public final net.corda.core.node.services.Vault$Page<T> copy(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends T>>, java.util.List<net.corda.core.node.services.Vault$StateMetadata>, long, net.corda.core.node.services.Vault$StateStatus, java.util.List<?>) public final net.corda.core.node.services.Vault$Page<T> copy(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends T>>, java.util.List<net.corda.core.node.services.Vault$StateMetadata>, long, net.corda.core.node.services.Vault$StateStatus, java.util.List<?>)
@NotNull
public final net.corda.core.node.services.Vault$Page<T> copy(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends T>>, java.util.List<net.corda.core.node.services.Vault$StateMetadata>, long, net.corda.core.node.services.Vault$StateStatus, java.util.List<?>, net.corda.core.contracts.StateRef)
public boolean equals(Object) public boolean equals(Object)
@NotNull @NotNull
public final java.util.List<Object> getOtherResults() public final java.util.List<Object> getOtherResults()
@Nullable
public final net.corda.core.contracts.StateRef getPreviousPageAnchor()
@NotNull @NotNull
public final net.corda.core.node.services.Vault$StateStatus getStateTypes() public final net.corda.core.node.services.Vault$StateStatus getStateTypes()
@NotNull @NotNull
@ -8380,10 +8565,12 @@ 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, 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, boolean, boolean, boolean, java.util.List, java.util.List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters, 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>) 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>)
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, 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<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.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, 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.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<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.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, 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.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, java.util.Map<String, ?>, boolean, java.util.Collection<? extends net.corda.testing.node.TestCordapp>, java.util.Map<String, String>, boolean, boolean, java.time.Duration)
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.util.Map, boolean, boolean, java.time.Duration, 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 <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() public final boolean component1()
@NotNull @NotNull
@ -8397,16 +8584,14 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O
public final boolean component14() public final boolean component14()
@Nullable @Nullable
public final java.util.Collection<net.corda.testing.node.TestCordapp> component15() public final java.util.Collection<net.corda.testing.node.TestCordapp> component15()
@Nullable
public final java.nio.file.Path component16()
@NotNull @NotNull
public final java.util.List<java.nio.file.Path> component17() public final java.util.Map<String, String> component16()
public final boolean component17()
public final boolean component18()
@NotNull @NotNull
public final java.util.Map<String, String> component18() public final java.time.Duration component19()
public final boolean component19()
@NotNull @NotNull
public final java.nio.file.Path component2() public final java.nio.file.Path component2()
public final boolean component20()
@NotNull @NotNull
public final net.corda.testing.driver.PortAllocation component3() public final net.corda.testing.driver.PortAllocation component3()
@NotNull @NotNull
@ -8423,9 +8608,11 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O
@NotNull @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>) 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>)
@NotNull @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) 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.util.Map<String, String>, boolean)
@NotNull @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) 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.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.Map<String, ?>, boolean, java.util.Collection<? extends net.corda.testing.node.TestCordapp>, java.util.Map<String, String>, boolean, boolean, java.time.Duration)
@NotNull @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 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 boolean equals(Object)
@ -8434,10 +8621,6 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O
public final java.util.Collection<net.corda.testing.node.TestCordapp> getCordappsForAllNodes() public final java.util.Collection<net.corda.testing.node.TestCordapp> getCordappsForAllNodes()
@NotNull @NotNull
public final net.corda.testing.driver.PortAllocation getDebugPortAllocation() public final net.corda.testing.driver.PortAllocation getDebugPortAllocation()
@Nullable
public final java.nio.file.Path getDjvmBootstrapSource()
@NotNull
public final java.util.List<java.nio.file.Path> getDjvmCordaSource()
@NotNull @NotNull
public final java.nio.file.Path getDriverDirectory() public final java.nio.file.Path getDriverDirectory()
@NotNull @NotNull
@ -8452,6 +8635,8 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O
@NotNull @NotNull
public final java.util.Map<String, Object> getNotaryCustomOverrides() public final java.util.Map<String, Object> getNotaryCustomOverrides()
@NotNull @NotNull
public final java.time.Duration getNotaryHandleTimeout()
@NotNull
public final java.util.List<net.corda.testing.node.NotarySpec> getNotarySpecs() public final java.util.List<net.corda.testing.node.NotarySpec> getNotarySpecs()
@NotNull @NotNull
public final net.corda.testing.driver.PortAllocation getPortAllocation() public final net.corda.testing.driver.PortAllocation getPortAllocation()
@ -8472,10 +8657,6 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O
@NotNull @NotNull
public final net.corda.testing.driver.DriverParameters withDebugPortAllocation(net.corda.testing.driver.PortAllocation) public final net.corda.testing.driver.DriverParameters withDebugPortAllocation(net.corda.testing.driver.PortAllocation)
@NotNull @NotNull
public final net.corda.testing.driver.DriverParameters withDjvmBootstrapSource(java.nio.file.Path)
@NotNull
public final net.corda.testing.driver.DriverParameters withDjvmCordaSource(java.util.List<? extends java.nio.file.Path>)
@NotNull
public final net.corda.testing.driver.DriverParameters withDriverDirectory(java.nio.file.Path) public final net.corda.testing.driver.DriverParameters withDriverDirectory(java.nio.file.Path)
@NotNull @NotNull
public final net.corda.testing.driver.DriverParameters withEnvironmentVariables(java.util.Map<String, String>) public final net.corda.testing.driver.DriverParameters withEnvironmentVariables(java.util.Map<String, String>)
@ -8492,6 +8673,8 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O
@NotNull @NotNull
public final net.corda.testing.driver.DriverParameters withNotaryCustomOverrides(java.util.Map<String, ?>) public final net.corda.testing.driver.DriverParameters withNotaryCustomOverrides(java.util.Map<String, ?>)
@NotNull @NotNull
public final net.corda.testing.driver.DriverParameters withNotaryHandleTimeout(java.time.Duration)
@NotNull
public final net.corda.testing.driver.DriverParameters withNotarySpecs(java.util.List<net.corda.testing.node.NotarySpec>) public final net.corda.testing.driver.DriverParameters withNotarySpecs(java.util.List<net.corda.testing.node.NotarySpec>)
@NotNull @NotNull
public final net.corda.testing.driver.DriverParameters withPortAllocation(net.corda.testing.driver.PortAllocation) public final net.corda.testing.driver.DriverParameters withPortAllocation(net.corda.testing.driver.PortAllocation)
@ -8724,6 +8907,7 @@ public final class net.corda.testing.flows.FlowTestsUtilsKt extends java.lang.Ob
public static final java.util.Map<net.corda.core.flows.FlowSession, net.corda.core.utilities.UntrustworthyData<Object>> receiveAll(net.corda.core.flows.FlowLogic<?>, kotlin.Pair<? extends net.corda.core.flows.FlowSession, ? extends Class<?>>, kotlin.Pair<? extends net.corda.core.flows.FlowSession, ? extends Class<?>>...) public static final java.util.Map<net.corda.core.flows.FlowSession, net.corda.core.utilities.UntrustworthyData<Object>> receiveAll(net.corda.core.flows.FlowLogic<?>, kotlin.Pair<? extends net.corda.core.flows.FlowSession, ? extends Class<?>>, kotlin.Pair<? extends net.corda.core.flows.FlowSession, ? extends Class<?>>...)
@NotNull @NotNull
public static final rx.Observable<T> registerCoreFlowFactory(net.corda.testing.node.internal.TestStartedNode, Class<? extends net.corda.core.flows.FlowLogic<?>>, Class<T>, kotlin.jvm.functions.Function1<? super net.corda.core.flows.FlowSession, ? extends T>, boolean) public static final rx.Observable<T> registerCoreFlowFactory(net.corda.testing.node.internal.TestStartedNode, Class<? extends net.corda.core.flows.FlowLogic<?>>, Class<T>, kotlin.jvm.functions.Function1<? super net.corda.core.flows.FlowSession, ? extends T>, boolean)
public static final void waitForAllFlowsToComplete(net.corda.testing.driver.NodeHandle, int, long)
## ##
@DoNotImplement @DoNotImplement
public abstract class net.corda.testing.node.ClusterSpec extends java.lang.Object public abstract class net.corda.testing.node.ClusterSpec extends java.lang.Object
@ -9145,7 +9329,9 @@ public class net.corda.testing.node.MockServices extends java.lang.Object implem
@NotNull @NotNull
public static final kotlin.Pair<net.corda.nodeapi.internal.persistence.CordaPersistence, net.corda.testing.node.MockServices> makeTestDatabaseAndPersistentServices(java.util.List<String>, net.corda.testing.core.TestIdentity, net.corda.core.node.NetworkParameters, java.util.Set<java.security.KeyPair>, java.util.Set<net.corda.core.identity.PartyAndCertificate>, net.corda.testing.internal.TestingNamedCacheFactory) public static final kotlin.Pair<net.corda.nodeapi.internal.persistence.CordaPersistence, net.corda.testing.node.MockServices> makeTestDatabaseAndPersistentServices(java.util.List<String>, net.corda.testing.core.TestIdentity, net.corda.core.node.NetworkParameters, java.util.Set<java.security.KeyPair>, java.util.Set<net.corda.core.identity.PartyAndCertificate>, net.corda.testing.internal.TestingNamedCacheFactory)
public void recordTransactions(Iterable<net.corda.core.transactions.SignedTransaction>) public void recordTransactions(Iterable<net.corda.core.transactions.SignedTransaction>)
public final void recordTransactions(Iterable<net.corda.core.transactions.SignedTransaction>, boolean)
public void recordTransactions(net.corda.core.node.StatesToRecord, Iterable<net.corda.core.transactions.SignedTransaction>) public void recordTransactions(net.corda.core.node.StatesToRecord, Iterable<net.corda.core.transactions.SignedTransaction>)
public final void recordTransactions(net.corda.core.transactions.SignedTransaction, boolean)
public void recordTransactions(net.corda.core.transactions.SignedTransaction, net.corda.core.transactions.SignedTransaction...) public void recordTransactions(net.corda.core.transactions.SignedTransaction, net.corda.core.transactions.SignedTransaction...)
public void recordTransactions(boolean, Iterable<net.corda.core.transactions.SignedTransaction>) public void recordTransactions(boolean, Iterable<net.corda.core.transactions.SignedTransaction>)
public void recordTransactions(boolean, net.corda.core.transactions.SignedTransaction, net.corda.core.transactions.SignedTransaction...) public void recordTransactions(boolean, net.corda.core.transactions.SignedTransaction, net.corda.core.transactions.SignedTransaction...)

View File

@ -13,13 +13,13 @@
* the branch name of origin branch, it should match the current branch * the branch name of origin branch, it should match the current branch
* and it acts as a fail-safe inside {@code forwardMerger} pipeline * and it acts as a fail-safe inside {@code forwardMerger} pipeline
*/ */
String originBranch = 'release/os/4.10' String originBranch = 'release/os/4.11'
/** /**
* the branch name of target branch, it should be the branch with the next version * the branch name of target branch, it should be the branch with the next version
* after the one in current branch. * after the one in current branch.
*/ */
String targetBranch = 'release/os/4.11' String targetBranch = 'release/os/4.12'
/** /**
* Forward merge any changes between #originBranch and #targetBranch * Forward merge any changes between #originBranch and #targetBranch

View File

@ -53,6 +53,7 @@ pipeline {
steps { steps {
authenticateGradleWrapper() authenticateGradleWrapper()
sh 'mkdir -p ${GRADLE_USER_HOME}' sh 'mkdir -p ${GRADLE_USER_HOME}'
authenticateGradleWrapper()
snykDeltaScan(env.SNYK_API_TOKEN, env.C4_OS_SNYK_ORG_ID) snykDeltaScan(env.SNYK_API_TOKEN, env.C4_OS_SNYK_ORG_ID)
} }
} }

8
.github/CODEOWNERS vendored
View File

@ -7,14 +7,6 @@ node-api @rick-r3
node/src/main/kotlin/net/corda/node/internal @rick-r3 node/src/main/kotlin/net/corda/node/internal @rick-r3
node/src/main/kotlin/net/corda/node/services @rick-r3 node/src/main/kotlin/net/corda/node/services @rick-r3
# Determinstic components
core-deterministic @rick-r3
jdk8u-deterministic @rick-r3
node/djvm @rick-r3
serialization-deterministic @rick-r3
serialization-djvm @rick-r3
serialization-tests @rick-r3
# Demobench defaults to Chris, but Viktor for the main code # Demobench defaults to Chris, but Viktor for the main code
tools/demobench @rick-r3 tools/demobench @rick-r3

View File

@ -9,6 +9,6 @@ jobs:
steps: steps:
- uses: morrisoncole/pr-lint-action@v1.6.1 - uses: morrisoncole/pr-lint-action@v1.6.1
with: with:
title-regex: '^((CORDA|AG|EG|ENT|INFRA|ES)-\d+|NOTICK)(.*)' title-regex: '^((CORDA|AG|EG|ENT|INFRA|ES)-\d+)(.*)'
on-failed-regex-comment: "PR title failed to match regex -> `%regex%`" on-failed-regex-comment: "PR title failed to match regex -> `%regex%`"
repo-token: "${{ secrets.GITHUB_TOKEN }}" repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -75,8 +75,6 @@ buildscript {
ext.disruptor_version = constants.getProperty("disruptorVersion") ext.disruptor_version = constants.getProperty("disruptorVersion")
ext.metrics_version = constants.getProperty("metricsVersion") ext.metrics_version = constants.getProperty("metricsVersion")
ext.metrics_new_relic_version = constants.getProperty("metricsNewRelicVersion") ext.metrics_new_relic_version = constants.getProperty("metricsNewRelicVersion")
ext.djvm_version = constants.getProperty("djvmVersion")
ext.deterministic_rt_version = constants.getProperty('deterministicRtVersion')
ext.okhttp_version = constants.getProperty("okhttpVersion") ext.okhttp_version = constants.getProperty("okhttpVersion")
ext.netty_version = constants.getProperty("nettyVersion") ext.netty_version = constants.getProperty("nettyVersion")
ext.tcnative_version = constants.getProperty("tcnativeVersion") ext.tcnative_version = constants.getProperty("tcnativeVersion")
@ -134,9 +132,6 @@ buildscript {
ext.fontawesomefx_fontawesome_version = constants.getProperty("fontawesomefxFontawesomeVersion") ext.fontawesomefx_fontawesome_version = constants.getProperty("fontawesomefxFontawesomeVersion")
} }
// Name of the IntelliJ SDK created for the deterministic Java rt.jar.
// ext.deterministic_idea_sdk = '1.8 (Deterministic)'
// Update 121 is required for ObjectInputFilter. // Update 121 is required for ObjectInputFilter.
// Updates [131, 161] also have zip compression bugs on MacOS (High Sierra). // Updates [131, 161] also have zip compression bugs on MacOS (High Sierra).
// when the java version in NodeStartup.hasMinimumJavaVersion() changes, so must this check // when the java version in NodeStartup.hasMinimumJavaVersion() changes, so must this check
@ -581,28 +576,6 @@ task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) {
it.exists() it.exists()
}) })
} }
afterEvaluate {
classDirectories = files(classDirectories.files.collect {
fileTree(dir: it,
// these exclusions are necessary because jacoco gets confused by same class names
// which occur due to deterministic versions of non deterministic classes
exclude: ['**/net/corda/core/crypto/DigestSupplier**',
'**/net/corda/core/crypto/DelegatingSecureRandomService',
'**/net/corda/core/internal/ThreadLocalToggleField**',
'**/net/corda/core/internal/InheritableThreadLocalToggleField**',
'**/net/corda/core/internal/ToggleField**',
'net/corda/core/internal/rules/StateContractValidationEnforcementRule**',
'net/corda/core/internal/SimpleToggleField**',
'net/corda/core/serialization/SerializationFactory**',
'net/corda/serialization/internal/amqp/AMQPStreams**',
'net/corda/serialization/internal/amqp/AMQPSerializerFactories**',
'net/corda/serialization/internal/amqp/AMQPSerializationThreadContext**',
'net/corda/serialization/internal/ByteBufferStreams**',
'net/corda/serialization/internal/model/DefaultCacheProvider**',
'net/corda/serialization/internal/DefaultWhitelist**'
])
})
}
} }
tasks.register('detekt', JavaExec) { tasks.register('detekt', JavaExec) {
@ -655,15 +628,11 @@ bintrayConfig {
'corda-mock', 'corda-mock',
'corda-rpc', 'corda-rpc',
'corda-core', 'corda-core',
'corda-core-deterministic',
'corda-deterministic-verifier',
'corda-deserializers-djvm',
'corda', 'corda',
'corda-finance-workflows', 'corda-finance-workflows',
'corda-finance-contracts', 'corda-finance-contracts',
'corda-node', 'corda-node',
'corda-node-api', 'corda-node-api',
'corda-node-djvm',
'corda-test-common', 'corda-test-common',
'corda-core-test-utils', 'corda-core-test-utils',
'corda-test-utils', 'corda-test-utils',
@ -676,8 +645,6 @@ bintrayConfig {
'corda-shell', 'corda-shell',
'corda-tools-shell-cli', 'corda-tools-shell-cli',
'corda-serialization', 'corda-serialization',
'corda-serialization-deterministic',
'corda-serialization-djvm',
'corda-tools-blob-inspector', 'corda-tools-blob-inspector',
'corda-tools-explorer', 'corda-tools-explorer',
'corda-tools-network-bootstrapper', 'corda-tools-network-bootstrapper',
@ -808,8 +775,4 @@ distributedTesting {
distribution DistributeTestsBy.METHOD distribution DistributeTestsBy.METHOD
} }
} }
ignoredTests = [
':core-deterministic:testing:data:test'
]
} }

View File

@ -9,4 +9,4 @@ package net.corda.common.logging
* (originally added to source control for ease of use) * (originally added to source control for ease of use)
*/ */
internal const val CURRENT_MAJOR_RELEASE = "4.10-SNAPSHOT" internal const val CURRENT_MAJOR_RELEASE = "4.11-SNAPSHOT"

View File

@ -3,7 +3,7 @@
# their own projects. So don't get fancy with syntax! # their own projects. So don't get fancy with syntax!
# Fancy syntax - multi pass ${whatever} replacement # Fancy syntax - multi pass ${whatever} replacement
cordaVersion=4.10 cordaVersion=4.11
versionSuffix=SNAPSHOT versionSuffix=SNAPSHOT
gradlePluginsVersion=5.0.12 gradlePluginsVersion=5.0.12
kotlinVersion=1.2.71 kotlinVersion=1.2.71
@ -12,7 +12,7 @@ java8MinUpdateVersion=171
# When incrementing platformVersion make sure to update # # When incrementing platformVersion make sure to update #
# net.corda.core.internal.CordaUtilsKt.PLATFORM_VERSION as well. # # net.corda.core.internal.CordaUtilsKt.PLATFORM_VERSION as well. #
# ***************************************************************# # ***************************************************************#
platformVersion=12 platformVersion=13
openTelemetryVersion=1.20.1 openTelemetryVersion=1.20.1
openTelemetrySemConvVersion=1.20.1-alpha openTelemetrySemConvVersion=1.20.1-alpha
guavaVersion=28.0-jre guavaVersion=28.0-jre
@ -24,7 +24,7 @@ jdkClassifier11=jdk11
dockerJavaVersion=3.2.5 dockerJavaVersion=3.2.5
proguardVersion=6.1.1 proguardVersion=6.1.1
// bouncy castle version must not be changed on a patch release. Needs a full release test cycle to flush out any issues. // bouncy castle version must not be changed on a patch release. Needs a full release test cycle to flush out any issues.
bouncycastleVersion=1.70 bouncycastleVersion=1.75
classgraphVersion=4.8.135 classgraphVersion=4.8.135
disruptorVersion=3.4.2 disruptorVersion=3.4.2
typesafeConfigVersion=1.3.4 typesafeConfigVersion=1.3.4
@ -34,8 +34,6 @@ snakeYamlVersion=1.33
caffeineVersion=2.9.3 caffeineVersion=2.9.3
metricsVersion=4.1.0 metricsVersion=4.1.0
metricsNewRelicVersion=1.1.1 metricsNewRelicVersion=1.1.1
djvmVersion=1.1.1
deterministicRtVersion=1.0-RC02
openSourceBranch=https://github.com/corda/corda/blob/release/os/4.4 openSourceBranch=https://github.com/corda/corda/blob/release/os/4.4
openSourceSamplesBranch=https://github.com/corda/samples/blob/release-V4 openSourceSamplesBranch=https://github.com/corda/samples/blob/release-V4
jolokiaAgentVersion=1.6.1 jolokiaAgentVersion=1.6.1
@ -78,9 +76,9 @@ mockitoKotlinVersion=1.6.0
hamkrestVersion=1.7.0.0 hamkrestVersion=1.7.0.0
joptSimpleVersion=5.0.2 joptSimpleVersion=5.0.2
jansiVersion=1.18 jansiVersion=1.18
hibernateVersion=5.4.32.Final hibernateVersion=5.6.14.Final
# h2Version - Update docs if renamed or removed. # h2Version - Update docs if renamed or removed.
h2Version=1.4.199 h2Version=2.1.214
rxjavaVersion=1.3.8 rxjavaVersion=1.3.8
dokkaVersion=0.10.1 dokkaVersion=0.10.1
eddsaVersion=0.3.0 eddsaVersion=0.3.0
@ -89,7 +87,7 @@ commonsCollectionsVersion=4.3
beanutilsVersion=1.9.4 beanutilsVersion=1.9.4
shiroVersion=1.10.0 shiroVersion=1.10.0
hikariVersion=3.3.1 hikariVersion=3.3.1
liquibaseVersion=3.6.3 liquibaseVersion=4.20.0
dockerComposeRuleVersion=1.5.0 dockerComposeRuleVersion=1.5.0
seleniumVersion=3.141.59 seleniumVersion=3.141.59
ghostdriverVersion=2.1.0 ghostdriverVersion=2.1.0

View File

@ -1,2 +0,0 @@
## corda-core-deterministic.
This artifact is a deterministic subset of the binary contents of `corda-core`.

View File

@ -1,245 +0,0 @@
import net.corda.gradle.jarfilter.JarFilterTask
import net.corda.gradle.jarfilter.MetaFixerTask
import proguard.gradle.ProGuardTask
import static org.gradle.api.JavaVersion.VERSION_1_8
plugins {
id 'org.jetbrains.kotlin.jvm'
id 'net.corda.plugins.publish-utils'
id 'com.jfrog.artifactory'
id 'java-library'
id 'idea'
}
apply from: "${rootProject.projectDir}/deterministic.gradle"
description 'Corda core (deterministic)'
evaluationDependsOn(":core")
// required by DJVM and Avian JVM (for running inside the SGX enclave) which only supports Java 8.
targetCompatibility = VERSION_1_8
def javaHome = System.getProperty('java.home')
def jarBaseName = "corda-${project.name}".toString()
configurations {
deterministicLibraries {
canBeConsumed = false
extendsFrom api
}
deterministicArtifacts.extendsFrom deterministicLibraries
}
dependencies {
compileOnly project(':core')
// Configure these by hand. It should be a minimal subset of core's dependencies,
// and without any obviously non-deterministic ones such as Hibernate.
// These "api" dependencies will become "compile" scoped in our published POM.
api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
api "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
api "javax.persistence:javax.persistence-api:2.2"
api "com.google.code.findbugs:jsr305:$jsr305_version"
api "org.slf4j:slf4j-api:$slf4j_version"
compileOnly "io.opentelemetry:opentelemetry-api:${open_telemetry_version}"
compileOnly project(':opentelemetry')
// These dependencies will become "runtime" scoped in our published POM.
// See publish.dependenciesFrom.defaultScope.
deterministicLibraries "org.bouncycastle:bcprov-jdk15on:$bouncycastle_version"
deterministicLibraries "org.bouncycastle:bcpkix-jdk15on:$bouncycastle_version"
deterministicLibraries "net.i2p.crypto:eddsa:$eddsa_version"
}
tasks.named('jar', Jar) {
archiveBaseName = 'DOES-NOT-EXIST'
// Don't build a jar here because it would be the wrong one.
// The jar we really want will be built by the metafix task.
enabled = false
}
def coreJarTask = project(':core').tasks.named('jar', Jar)
def originalJar = coreJarTask.map { it.outputs.files.singleFile }
def patchCore = tasks.register('patchCore', Zip) {
dependsOn coreJarTask
destinationDirectory = layout.buildDirectory.dir('source-libs')
metadataCharset 'UTF-8'
archiveClassifier = 'transient'
archiveExtension = 'jar'
from(compileKotlin)
from(processResources)
from(zipTree(originalJar)) {
exclude 'net/corda/core/crypto/DelegatingSecureRandomService*.class'
exclude 'net/corda/core/crypto/DigestSupplier.class'
exclude 'net/corda/core/internal/*ToggleField*.class'
exclude 'net/corda/core/serialization/*SerializationFactory*.class'
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
includeEmptyDirs = false
}
def predeterminise = tasks.register('predeterminise', ProGuardTask) {
injars patchCore
outjars file("$buildDir/proguard/pre-deterministic-${project.version}.jar")
if (JavaVersion.current().isJava9Compatible()) {
libraryjars "$javaHome/jmods"
} else {
libraryjars "$javaHome/lib/rt.jar"
libraryjars "$javaHome/lib/jce.jar"
}
configurations.compileClasspath.forEach {
if (originalJar != it) {
libraryjars it, filter: '!META-INF/versions/**'
}
}
keepattributes '*'
keepdirectories
dontwarn '**$1$1,org.hibernate.annotations.*'
dontpreverify
dontobfuscate
dontoptimize
dontnote
printseeds
verbose
keep '@interface net.corda.core.* { *; }'
keep '@interface net.corda.core.contracts.** { *; }'
keep '@interface net.corda.core.serialization.** { *; }'
keep '@net.corda.core.KeepForDJVM class * { *; }', includedescriptorclasses:true
keepclassmembers 'class net.corda.core.** { public synthetic <methods>; }'
}
def jarFilter = tasks.register('jarFilter', JarFilterTask) {
jars predeterminise
annotations {
forDelete = [
"net.corda.core.DeleteForDJVM"
]
forStub = [
"net.corda.core.StubOutForDJVM"
]
forRemove = [
"co.paralleluniverse.fibers.Suspendable",
"org.hibernate.annotations.Immutable"
]
forSanitise = [
"net.corda.core.DeleteForDJVM"
]
}
}
def determinise = tasks.register('determinise', ProGuardTask) {
injars jarFilter
outjars file("$buildDir/proguard/$jarBaseName-${project.version}.jar")
if (JavaVersion.current().isJava9Compatible()) {
libraryjars "$javaHome/jmods"
} else {
libraryjars "$javaHome/lib/rt.jar"
libraryjars "$javaHome/lib/jce.jar"
}
configurations.deterministicLibraries.forEach {
libraryjars it, filter: '!META-INF/versions/**'
}
// Analyse the JAR for dead code, and remove (some of) it.
optimizations 'code/removal/simple,code/removal/advanced'
printconfiguration
keepattributes '*'
keepdirectories
dontobfuscate
dontnote
printseeds
verbose
keep '@interface net.corda.core.CordaInternal { *; }'
keep '@interface net.corda.core.DoNotImplement { *; }'
keep '@interface net.corda.core.KeepForDJVM { *; }'
keep '@interface net.corda.core.contracts.** { *; }'
keep '@interface net.corda.core.serialization.** { *; }'
keep '@net.corda.core.KeepForDJVM class * { *; }', includedescriptorclasses:true
keepclassmembers 'class net.corda.core.** { public synthetic <methods>; }'
}
def checkDeterminism = tasks.register('checkDeterminism', ProGuardTask)
def metafix = tasks.register('metafix', MetaFixerTask) {
outputDir = layout.buildDirectory.dir('libs')
jars determinise
suffix ""
// Strip timestamps from the JAR to make it reproducible.
preserveTimestamps = false
finalizedBy checkDeterminism
}
// DOCSTART 01
checkDeterminism.configure {
dependsOn jdkTask
injars metafix
libraryjars deterministic_rt_jar
configurations.deterministicLibraries.forEach {
libraryjars it, filter: '!META-INF/versions/**'
}
keepattributes '*'
dontpreverify
dontobfuscate
dontoptimize
verbose
keep 'class *'
}
// DOCEND 01
defaultTasks "determinise"
determinise.configure {
finalizedBy metafix
}
tasks.named('assemble') {
dependsOn checkDeterminism
}
def deterministicJar = metafix.map { it.outputs.files.singleFile }
artifacts {
deterministicArtifacts deterministicJar
publish deterministicJar
}
tasks.named('sourceJar', Jar) {
from 'README.md'
include 'README.md'
}
tasks.named('javadocJar', Jar) {
from 'README.md'
include 'README.md'
}
publish {
dependenciesFrom configurations.deterministicArtifacts
name jarBaseName
}
idea {
module {
if (project.hasProperty("deterministic_idea_sdk")) {
jdkName project.property("deterministic_idea_sdk") as String
}
}
}

View File

@ -1,19 +0,0 @@
package net.corda.core.crypto
import java.security.Provider
import java.security.SecureRandomSpi
@Suppress("unused")
class DelegatingSecureRandomService(provider: CordaSecurityProvider)
: Provider.Service(provider, "SecureRandom", "dummy-algorithm", UnsupportedSecureRandomSpi::javaClass.name, null, null) {
private val instance: SecureRandomSpi = UnsupportedSecureRandomSpi(algorithm)
override fun newInstance(param: Any?) = instance
private class UnsupportedSecureRandomSpi(private val algorithm: String) : SecureRandomSpi() {
override fun engineSetSeed(seed: ByteArray) = unsupported()
override fun engineNextBytes(bytes: ByteArray) = unsupported()
override fun engineGenerateSeed(numBytes: Int) = unsupported()
private fun unsupported(): Nothing = throw UnsupportedOperationException("$algorithm not supported")
}
}

View File

@ -1,10 +0,0 @@
package net.corda.core.crypto
import net.corda.core.crypto.internal.DigestAlgorithmFactory
import java.util.function.Supplier
@Suppress("unused")
private class DigestSupplier(private val algorithm: String) : Supplier<DigestAlgorithm> {
override fun get(): DigestAlgorithm = DigestAlgorithmFactory.create(algorithm)
val digestLength: Int by lazy { get().digestLength }
}

View File

@ -1,62 +0,0 @@
package net.corda.core.internal
import net.corda.core.KeepForDJVM
import net.corda.core.utilities.contextLogger
import org.slf4j.Logger
import kotlin.reflect.KProperty
/** May go from null to non-null and vice-versa, and that's it. */
abstract class ToggleField<T>(val name: String) {
abstract fun get(): T?
fun set(value: T?) {
if (value != null) {
check(get() == null) { "$name already has a value." }
setImpl(value)
} else {
check(get() != null) { "$name is already null." }
clear()
}
}
protected abstract fun setImpl(value: T)
protected abstract fun clear()
operator fun getValue(thisRef: Any?, property: KProperty<*>) = get()
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) = set(value)
}
@KeepForDJVM
class SimpleToggleField<T>(name: String, private val once: Boolean = false) : ToggleField<T>(name) {
private var holder: T? = null // Force T? in API for safety.
override fun get() = holder
override fun setImpl(value: T) { holder = value }
override fun clear() {
check(!once) { "Value of $name cannot be changed." }
holder = null
}
}
@KeepForDJVM
class ThreadLocalToggleField<T>(name: String) : ToggleField<T>(name) {
private var holder: T? = null // Force T? in API for safety.
override fun get() = holder
override fun setImpl(value: T) { holder = value }
override fun clear() {
holder = null
}
}
@Suppress("UNUSED")
@KeepForDJVM
class InheritableThreadLocalToggleField<T>(name: String,
private val log: Logger = staticLog,
private val isAGlobalThreadBeingCreated: (Array<StackTraceElement>) -> Boolean) : ToggleField<T>(name) {
private companion object {
private val staticLog = contextLogger()
}
private var holder: T? = null // Force T? in API for safety.
override fun get() = holder
override fun setImpl(value: T) { holder = value }
override fun clear() {
holder = null
}
}

View File

@ -1,12 +0,0 @@
package net.corda.core.internal.rules
import net.corda.core.contracts.ContractState
// This file provides rules that depend on the targetVersion of the current Contract or Flow.
// In core, this is determined by means which are unavailable in the DJVM,
// so we must provide deterministic alternatives here.
@Suppress("unused")
object StateContractValidationEnforcementRule {
fun shouldEnforce(@Suppress("UNUSED_PARAMETER") state: ContractState): Boolean = true
}

View File

@ -1,16 +0,0 @@
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

@ -1,99 +0,0 @@
package net.corda.core.serialization
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.internal.effectiveSerializationEnv
import net.corda.core.utilities.ByteSequence
/**
* An abstraction for serializing and deserializing objects, with support for versioning of the wire format via
* a header / prefix in the bytes.
*/
@KeepForDJVM
abstract class SerializationFactory {
/**
* Deserialize the bytes in to an object, using the prefixed bytes to determine the format.
*
* @param byteSequence The bytes to deserialize, including a format header prefix.
* @param clazz The class or superclass or the object to be deserialized, or [Any] or [Object] if unknown.
* @param context A context that configures various parameters to deserialization.
*/
abstract fun <T : Any> deserialize(byteSequence: ByteSequence, clazz: Class<T>, context: SerializationContext): T
/**
* Deserialize the bytes in to an object, using the prefixed bytes to determine the format.
*
* @param byteSequence The bytes to deserialize, including a format header prefix.
* @param clazz The class or superclass or the object to be deserialized, or [Any] or [Object] if unknown.
* @param context A context that configures various parameters to deserialization.
* @return deserialized object along with [SerializationContext] to identify encoding used.
*/
abstract fun <T : Any> deserializeWithCompatibleContext(byteSequence: ByteSequence, clazz: Class<T>, context: SerializationContext): ObjectWithCompatibleContext<T>
/**
* Serialize an object to bytes using the preferred serialization format version from the context.
*
* @param obj The object to be serialized.
* @param context A context that configures various parameters to serialization, including the serialization format version.
*/
abstract fun <T : Any> serialize(obj: T, context: SerializationContext): SerializedBytes<T>
/**
* If there is a need to nest serialization/deserialization with a modified context during serialization or deserialization,
* this will return the current context used to start serialization/deserialization.
*/
val currentContext: SerializationContext? get() = _currentContext
/**
* A context to use as a default if you do not require a specially configured context. It will be the current context
* if the use is somehow nested (see [currentContext]).
*/
val defaultContext: SerializationContext get() = currentContext ?: effectiveSerializationEnv.p2pContext
private var _currentContext: SerializationContext? = null
/**
* Change the current context inside the block to that supplied.
*/
fun <T> withCurrentContext(context: SerializationContext?, block: () -> T): T {
return if (context == null) {
block()
} else {
val priorContext = _currentContext
_currentContext = context
try {
block()
} finally {
_currentContext = priorContext
}
}
}
/**
* Allow subclasses to temporarily mark themselves as the current factory for the current thread during serialization/deserialization.
* Will restore the prior context on exiting the block.
*/
fun <T> asCurrent(block: SerializationFactory.() -> T): T {
val priorContext = _currentFactory
_currentFactory= this
try {
return this.block()
} finally {
_currentFactory = priorContext
}
}
companion object {
private var _currentFactory: SerializationFactory? = null
/**
* A default factory for serialization/deserialization, taking into account the [currentFactory] if set.
*/
val defaultFactory: SerializationFactory get() = currentFactory ?: effectiveSerializationEnv.serializationFactory
/**
* If there is a need to nest serialization/deserialization with a modified context during serialization or deserialization,
* this will return the current factory used to start serialization/deserialization.
*/
val currentFactory: SerializationFactory? get() = _currentFactory
}
}

View File

@ -1,23 +0,0 @@
package net.corda.core.serialization.internal
import net.corda.core.contracts.Attachment
import java.net.URL
@Suppress("unused")
private class AttachmentsHolderImpl : AttachmentsHolder {
private val attachments = LinkedHashMap<URL, Pair<URL, Attachment>>()
override val size: Int get() = attachments.size
override fun getKey(key: URL): URL? {
return attachments[key]?.first
}
override fun get(key: URL): Attachment? {
return attachments[key]?.second
}
override fun set(key: URL, value: Attachment) {
attachments[key] = key to value
}
}

View File

@ -1,29 +0,0 @@
plugins {
id 'org.jetbrains.kotlin.jvm'
}
dependencies {
testImplementation project(path: ':core-deterministic', configuration: 'deterministicArtifacts')
testImplementation project(path: ':serialization-deterministic', configuration: 'deterministicArtifacts')
testImplementation project(path: ':core-deterministic:testing:verifier', configuration: 'deterministicArtifacts')
testImplementation project(path: ':core-deterministic:testing:data', configuration: 'testData')
testImplementation(project(':finance:contracts')) {
transitive = false
}
testImplementation(project(':finance:workflows')) {
transitive = false
}
testImplementation "org.slf4j:slf4j-api:$slf4j_version"
testRuntimeOnly "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testImplementation "org.assertj:assertj-core:$assertj_version"
testImplementation "junit:junit:$junit_version"
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
}
// This module has no artifact and only contains tests.
tasks.named('jar', Jar) {
enabled = false
}

View File

@ -1,44 +0,0 @@
plugins {
id 'org.jetbrains.kotlin.jvm'
}
configurations {
testData {
canBeResolved = false
}
}
dependencies {
testImplementation project(':core')
testImplementation project(':finance:workflows')
testImplementation project(':node-driver')
testImplementation project(path: ':core-deterministic:testing:verifier', configuration: 'runtimeArtifacts')
testImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testImplementation "org.jetbrains.kotlin:kotlin-reflect"
testImplementation "junit:junit:$junit_version"
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
}
tasks.named('jar', Jar) {
enabled = false
}
def test = tasks.named('test', Test) {
filter {
// Running this class is the whole point, so include it explicitly.
includeTestsMatching "net.corda.deterministic.data.GenerateData"
}
// force execution of these tests to generate artifacts required by other module (eg. VerifyTransactionTest)
// note: required by Gradle Build Cache.
outputs.upToDateWhen { false }
}
def testDataJar = file("$buildDir/test-data.jar")
artifacts {
archives file: testDataJar, type: 'jar', builtBy: test
testData file: testDataJar, type: 'jar', builtBy: test
}

View File

@ -1,92 +0,0 @@
package net.corda.deterministic.data
import net.corda.core.serialization.deserialize
import net.corda.deterministic.verifier.LocalSerializationRule
import net.corda.deterministic.verifier.TransactionVerificationRequest
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import java.io.FileNotFoundException
import java.net.URLClassLoader
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.attribute.FileTime
import java.util.*
import java.util.Calendar.*
import java.util.jar.JarOutputStream
import java.util.zip.Deflater.NO_COMPRESSION
import java.util.zip.ZipEntry
import java.util.zip.ZipEntry.*
import kotlin.reflect.jvm.jvmName
/**
* Use the JUnit framework to generate a JAR of test data.
*/
class GenerateData {
companion object {
private val CONSTANT_TIME: FileTime = FileTime.fromMillis(
GregorianCalendar(1980, FEBRUARY, 1).apply { timeZone = TimeZone.getTimeZone("UTC") }.timeInMillis
)
private const val KEYSTORE_ALIAS = "tx"
private val KEYSTORE_PASSWORD = "deterministic".toCharArray()
private val TEST_DATA: Path = Paths.get("build", "test-data.jar")
private fun compressed(name: String) = ZipEntry(name).apply {
lastModifiedTime = CONSTANT_TIME
method = DEFLATED
}
private fun directory(name: String) = ZipEntry(name).apply {
lastModifiedTime = CONSTANT_TIME
method = STORED
compressedSize = 0
size = 0
crc = 0
}
}
@Rule
@JvmField
val testSerialization = LocalSerializationRule(GenerateData::class.jvmName)
@Before
fun createTransactions() {
JarOutputStream(Files.newOutputStream(TEST_DATA)).use { jar ->
jar.setComment("Test data for Deterministic Corda")
jar.setLevel(NO_COMPRESSION)
// Serialised transactions for the Enclavelet
jar.putNextEntry(directory("txverify"))
jar.putNextEntry(compressed("txverify/tx-success.bin"))
TransactionGenerator.writeSuccess(jar)
jar.putNextEntry(compressed("txverify/tx-failure.bin"))
TransactionGenerator.writeFailure(jar)
// KeyStore containing an EC private key.
jar.putNextEntry(directory("keystore"))
jar.putNextEntry(compressed("keystore/txsignature.pfx"))
KeyStoreGenerator.writeKeyStore(jar, KEYSTORE_ALIAS, KEYSTORE_PASSWORD)
}
testSerialization.reset()
}
@Test(timeout = 300_000)
fun verifyTransactions() {
URLClassLoader(arrayOf(TEST_DATA.toUri().toURL())).use { cl ->
cl.loadResource("txverify/tx-success.bin")
.deserialize<TransactionVerificationRequest>()
.toLedgerTransaction()
.verify()
cl.loadResource("txverify/tx-failure.bin")
.deserialize<TransactionVerificationRequest>()
.toLedgerTransaction()
}
}
private fun ClassLoader.loadResource(resourceName: String): ByteArray {
return getResourceAsStream(resourceName)?.use { it.readBytes() }
?: throw FileNotFoundException(resourceName)
}
}

View File

@ -1,50 +0,0 @@
package net.corda.deterministic.data
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder
import java.io.OutputStream
import java.math.BigInteger.TEN
import java.security.KeyPairGenerator
import java.security.KeyStore
import java.security.spec.ECGenParameterSpec
import java.util.*
import java.util.Calendar.*
object KeyStoreGenerator {
private val keyPairGenerator: KeyPairGenerator = KeyPairGenerator.getInstance("EC").apply {
initialize(ECGenParameterSpec("secp256k1"))
}
fun writeKeyStore(output: OutputStream, alias: String, password: CharArray) {
val keyPair = keyPairGenerator.generateKeyPair()
val signer = JcaContentSignerBuilder("SHA256WithECDSA").build(keyPair.private)
val dname = X500Name("CN=Enclavelet")
val startDate = Calendar.getInstance().let { cal ->
cal.time = Date()
cal.add(HOUR, -1)
cal.time
}
val endDate = Calendar.getInstance().let { cal ->
cal.time = startDate
cal.add(YEAR, 1)
cal.time
}
val certificate = JcaX509v3CertificateBuilder(
dname,
TEN,
startDate,
endDate,
dname,
keyPair.public
).build(signer)
val x509 = JcaX509CertificateConverter().getCertificate(certificate)
KeyStore.getInstance("PKCS12").apply {
load(null, password)
setKeyEntry(alias, keyPair.private, password, arrayOf(x509))
store(output, password)
}
}
}

View File

@ -1,115 +0,0 @@
package net.corda.deterministic.data
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.node.services.IdentityService
import net.corda.core.serialization.serialize
import net.corda.deterministic.verifier.MockContractAttachment
import net.corda.deterministic.verifier.SampleCommandData
import net.corda.deterministic.verifier.TransactionVerificationRequest
import net.corda.finance.POUNDS
import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash.Commands.Issue
import net.corda.finance.contracts.asset.Cash.Commands.Move
import net.corda.finance.contracts.asset.Cash.Companion.PROGRAM_ID
import net.corda.finance.contracts.asset.Cash.State
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.TestIdentity
import net.corda.testing.core.getTestPartyAndCertificate
import net.corda.testing.node.MockServices
import net.corda.testing.node.ledger
import java.io.OutputStream
import java.math.BigInteger
import java.security.KeyPair
import java.security.PublicKey
object TransactionGenerator {
private val DUMMY_NOTARY: Party = TestIdentity(DUMMY_NOTARY_NAME, 20).party
private val DUMMY_CASH_ISSUER_KEY: KeyPair = entropyToKeyPair(BigInteger.valueOf(10))
private val DUMMY_CASH_ISSUER_IDENTITY = getTestPartyAndCertificate(Party(CordaX500Name("Snake Oil Issuer", "London", "GB"), DUMMY_CASH_ISSUER_KEY.public))
private val DUMMY_CASH_ISSUER = DUMMY_CASH_ISSUER_IDENTITY.party.ref(1)
private val megaCorp = TestIdentity(CordaX500Name("MegaCorp", "London", "GB"))
private val MEGA_CORP: Party = megaCorp.party
private val MEGA_CORP_PUBKEY: PublicKey = megaCorp.keyPair.public
private val MINI_CORP_PUBKEY: PublicKey = TestIdentity(CordaX500Name("MiniCorp", "London", "GB")).keyPair.public
private val ledgerServices = MockServices(emptyList(), MEGA_CORP.name, mock<IdentityService>().also {
doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY)
doReturn(DUMMY_CASH_ISSUER.party).whenever(it).partyFromKey(DUMMY_CASH_ISSUER_KEY.public)
})
fun writeSuccess(output: OutputStream) {
ledgerServices.ledger(DUMMY_NOTARY) {
// Issue a couple of cash states and spend them.
val wtx1 = transaction {
attachments(PROGRAM_ID)
output(PROGRAM_ID, "c1", State(1000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
command(DUMMY_CASH_ISSUER.party.owningKey, Issue())
verifies()
}
val wtx2 = transaction {
attachments(PROGRAM_ID)
output(PROGRAM_ID, "c2", State(2000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
command(DUMMY_CASH_ISSUER.party.owningKey, Issue())
verifies()
}
val wtx3 = transaction {
attachments(PROGRAM_ID)
input("c1")
input("c2")
output(PROGRAM_ID, "c3", State(3000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MINI_CORP_PUBKEY)))
command(MEGA_CORP_PUBKEY, Move())
verifies()
}
val contractAttachment = MockContractAttachment(interpreter.services.cordappProvider.getContractAttachmentID(PROGRAM_ID)!!, PROGRAM_ID)
TransactionVerificationRequest(
wtx3.serialize(),
arrayOf(wtx1.serialize(), wtx2.serialize()),
arrayOf(contractAttachment.serialize().bytes),
ledgerServices.networkParameters.serialize())
.serialize()
.writeTo(output)
}
}
fun writeFailure(output: OutputStream) {
ledgerServices.ledger(DUMMY_NOTARY) {
// Issue a couple of cash states and spend them.
val wtx1 = transaction {
attachments(PROGRAM_ID)
output(PROGRAM_ID, "c1", State(1000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
command(DUMMY_CASH_ISSUER.party.owningKey, Issue())
verifies()
}
val wtx2 = transaction {
attachments(PROGRAM_ID)
output(PROGRAM_ID, "c2", State(2000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
command(DUMMY_CASH_ISSUER.party.owningKey, Issue())
verifies()
}
val wtx3 = transaction {
attachments(PROGRAM_ID)
input("c1")
input("c2")
command(DUMMY_CASH_ISSUER.party.owningKey, SampleCommandData)
output(PROGRAM_ID, "c3", State(3000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MINI_CORP_PUBKEY)))
failsWith("Required ${Move::class.java.canonicalName} command")
}
val contractAttachment = MockContractAttachment(interpreter.services.cordappProvider.getContractAttachmentID(PROGRAM_ID)!!, PROGRAM_ID)
TransactionVerificationRequest(
wtx3.serialize(),
arrayOf(wtx1.serialize(), wtx2.serialize()),
arrayOf(contractAttachment.serialize().bytes),
ledgerServices.networkParameters.serialize())
.serialize()
.writeTo(output)
}
}
}

View File

@ -1,61 +0,0 @@
package net.corda.deterministic;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.SecureRandomSpi;
import java.security.Security;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.Assert.assertEquals;
/**
* Temporarily restore Sun's [SecureRandom] provider.
* This is ONLY for allowing us to generate test data, e.g. signatures.
*
* JDK11 upgrade: rewritten in Java to gain access to private internal JDK classes via module directives (not available to Kotlin compiler):
* sun.security.provider.SecureRandom()
*/
public class CheatingSecurityProvider extends Provider implements AutoCloseable {
private static AtomicInteger counter = new AtomicInteger();
@SuppressWarnings("deprecation") // JDK11: should replace with Provider(String name, double version, String info) (since 9)
public CheatingSecurityProvider() {
super("Cheat-" + counter.getAndIncrement(), 1.8, "Cheat security provider");
putService(new CheatingSecureRandomService(this));
assertEquals(1, Security.insertProviderAt(this, 1));
}
public void close() {
Security.removeProvider(getName());
}
private class SunSecureRandom extends SecureRandom {
public SunSecureRandom() {
// JDK11 upgrade: rewritten in Java to gain access to private internal JDK classes via open module directive
super(new sun.security.provider.SecureRandom(), null);
}
}
private class CheatingSecureRandomService extends Provider.Service {
public CheatingSecureRandomService(Provider provider) {
super(provider, "SecureRandom", "CheatingPRNG", CheatingSecureRandomSpi.class.getName(), null, null);
}
private SecureRandomSpi instance = new CheatingSecureRandomSpi();
public Object newInstance(Object constructorParameter){
return instance;
}
}
private class CheatingSecureRandomSpi extends SecureRandomSpi {
private SecureRandom secureRandom = new SunSecureRandom();
public void engineSetSeed(byte[] seed) { secureRandom.setSeed(seed); }
public void engineNextBytes(byte[] bytes) { secureRandom.nextBytes(bytes); }
public byte[] engineGenerateSeed(int numBytes) { return secureRandom.generateSeed(numBytes); }
}
}

View File

@ -1,9 +0,0 @@
package net.corda.core.internal
/**
* Stubbing out non-deterministic method.
*/
fun <T: Any> createInstancesOfClassesImplementing(@Suppress("UNUSED_PARAMETER") classloader: ClassLoader, @Suppress("UNUSED_PARAMETER") clazz: Class<T>,
@Suppress("UNUSED_PARAMETER") classVersionRange: IntRange? = null): Set<T> {
return emptySet()
}

View File

@ -1,70 +0,0 @@
package net.corda.deterministic
import net.corda.core.CordaException
import net.corda.core.contracts.AttachmentResolutionException
import net.corda.core.contracts.TransactionResolutionException
import net.corda.core.contracts.TransactionVerificationException.*
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import org.junit.Assert.*
import org.junit.Test
import java.security.PublicKey
import kotlin.test.assertFailsWith
class CordaExceptionTest {
companion object {
const val CONTRACT_CLASS = "com.r3.corda.contracts.TestContract"
val TEST_HASH = SecureHash.zeroHash
val TX_ID = SecureHash.allOnesHash
val ALICE_NAME = CordaX500Name("Alice Corp", "Madrid", "ES")
val ALICE_KEY: PublicKey = object : PublicKey {
override fun getAlgorithm(): String = "TEST-256"
override fun getFormat(): String = "<none>"
override fun getEncoded() = byteArrayOf()
}
val ALICE = Party(ALICE_NAME, ALICE_KEY)
val BOB_NAME = CordaX500Name("Bob Plc", "Rome", "IT")
val BOB_KEY: PublicKey = object : PublicKey {
override fun getAlgorithm(): String = "TEST-512"
override fun getFormat(): String = "<none>"
override fun getEncoded() = byteArrayOf()
}
val BOB = Party(BOB_NAME, BOB_KEY)
}
@Test(timeout=300_000)
fun testCordaException() {
val ex = assertFailsWith<CordaException> { throw CordaException("BAD THING") }
assertEquals("BAD THING", ex.message)
}
@Test(timeout=300_000)
fun testAttachmentResolutionException() {
val ex = assertFailsWith<AttachmentResolutionException> { throw AttachmentResolutionException(TEST_HASH) }
assertEquals(TEST_HASH, ex.hash)
}
@Test(timeout=300_000)
fun testTransactionResolutionException() {
val ex = assertFailsWith<TransactionResolutionException> { throw TransactionResolutionException(TEST_HASH) }
assertEquals(TEST_HASH, ex.hash)
}
@Test(timeout=300_000)
fun testConflictingAttachmentsRejection() {
val ex = assertFailsWith<ConflictingAttachmentsRejection> { throw ConflictingAttachmentsRejection(TX_ID, CONTRACT_CLASS) }
assertEquals(TX_ID, ex.txId)
assertEquals(CONTRACT_CLASS, ex.contractClass)
}
@Test(timeout=300_000)
fun testNotaryChangeInWrongTransactionType() {
val ex = assertFailsWith<NotaryChangeInWrongTransactionType> { throw NotaryChangeInWrongTransactionType(TX_ID, ALICE, BOB) }
assertEquals(TX_ID, ex.txId)
assertEquals(ALICE, ex.txNotary)
assertEquals(BOB, ex.outputNotary)
}
}

View File

@ -1,44 +0,0 @@
package net.corda.deterministic
import org.junit.AssumptionViolatedException
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
import java.security.KeyPair
import java.security.KeyStore
import java.security.PrivateKey
import java.security.cert.TrustAnchor
import java.security.cert.X509Certificate
class KeyStoreProvider(private val storeName: String, private val storePassword: String) : TestRule {
private lateinit var keyStore: KeyStore
private fun loadKeyStoreResource(resourceName: String, password: CharArray, type: String = "PKCS12"): KeyStore {
return KeyStore.getInstance(type).apply {
// Skip these tests if we cannot load the keystore.
val keyStream = KeyStoreProvider::class.java.classLoader.getResourceAsStream(resourceName)
?: throw AssumptionViolatedException("KeyStore $resourceName not found")
keyStream.use { input ->
load(input, password)
}
}
}
override fun apply(statement: Statement, description: Description?): Statement {
return object : Statement() {
override fun evaluate() {
keyStore = loadKeyStoreResource(storeName, storePassword.toCharArray())
statement.evaluate()
}
}
}
fun getKeyPair(alias: String): KeyPair {
val privateKey = keyStore.getKey(alias, storePassword.toCharArray()) as PrivateKey
return KeyPair(keyStore.getCertificate(alias).publicKey, privateKey)
}
@Suppress("UNUSED")
fun trustAnchorsFor(vararg aliases: String): Set<TrustAnchor>
= aliases.map { alias -> TrustAnchor(keyStore.getCertificate(alias) as X509Certificate, null) }.toSet()
}

View File

@ -1,14 +0,0 @@
package net.corda.deterministic
import java.io.ByteArrayOutputStream
import java.io.IOException
private val classLoader: ClassLoader = object {}.javaClass.classLoader
@Throws(IOException::class)
fun bytesOfResource(resourceName: String): ByteArray {
return ByteArrayOutputStream().let { baos ->
classLoader.getResourceAsStream(resourceName).copyTo(baos)
baos.toByteArray()
}
}

View File

@ -1,79 +0,0 @@
package net.corda.deterministic.contracts
import net.corda.core.contracts.Attachment
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import java.io.ByteArrayOutputStream
import java.io.InputStream
import java.security.PublicKey
import java.util.jar.JarOutputStream
import java.util.zip.Deflater.*
import java.util.zip.ZipEntry
class AttachmentTest {
private companion object {
private val data = byteArrayOf(0x73, 0x71, 0x18, 0x5F, 0x3A, 0x47, -0x22, 0x38)
private val jarData: ByteArray = ByteArrayOutputStream().let { baos ->
JarOutputStream(baos).use { jar ->
jar.setLevel(BEST_COMPRESSION)
jar.putNextEntry(ZipEntry("data.bin").apply { method = DEFLATED })
data.inputStream().copyTo(jar)
}
baos.toByteArray()
}
private val ALICE_NAME = CordaX500Name("Alice Corp", "Madrid", "ES")
private val ALICE_KEY: PublicKey = object : PublicKey {
override fun getAlgorithm(): String = "TEST-256"
override fun getFormat(): String = "<none>"
override fun getEncoded() = byteArrayOf()
}
private val ALICE = Party(ALICE_NAME, ALICE_KEY)
}
private lateinit var attachment: Attachment
@Before
fun setup() {
attachment = object : Attachment {
override val signerKeys: List<PublicKey>
get() = listOf(ALICE_KEY)
override val id: SecureHash
get() = SecureHash.allOnesHash
override val signers: List<Party>
get() = listOf(ALICE)
override val size: Int
get() = jarData.size
override fun open(): InputStream {
return jarData.inputStream()
}
}
}
@Test(timeout=300_000)
fun testAttachmentJar() {
attachment.openAsJAR().use { jar ->
val entry = jar.nextJarEntry ?: return@use
assertEquals("data.bin", entry.name)
val entryData = ByteArrayOutputStream().use {
jar.copyTo(it)
it.toByteArray()
}
assertArrayEquals(data, entryData)
}
}
@Test(timeout=300_000)
fun testExtractFromAttachment() {
val resultData = ByteArrayOutputStream().use {
attachment.extractFile("data.bin", it)
it.toByteArray()
}
assertArrayEquals(data, resultData)
}
}

View File

@ -1,28 +0,0 @@
package net.corda.deterministic.contracts
import net.corda.core.contracts.PrivacySalt
import org.junit.Test
import kotlin.test.*
class PrivacySaltTest {
private companion object {
private const val SALT_SIZE = 32
}
@Test(timeout=300_000)
fun testValidSalt() {
PrivacySalt(ByteArray(SALT_SIZE) { 0x14 })
}
@Test(timeout=300_000)
fun testInvalidSaltWithAllZeros() {
val ex = assertFailsWith<IllegalArgumentException> { PrivacySalt(ByteArray(SALT_SIZE)) }
assertEquals("Privacy salt should not be all zeros.", ex.message)
}
@Test(timeout=300_000)
fun testTooShortPrivacySaltForSHA256() {
val ex = assertFailsWith<IllegalArgumentException> { PrivacySalt(ByteArray(SALT_SIZE - 1) { 0x7f }) }
assertEquals("Privacy salt should be at least 32 bytes.", ex.message)
}
}

View File

@ -1,37 +0,0 @@
package net.corda.deterministic.contracts
import net.corda.core.contracts.UniqueIdentifier
import org.assertj.core.api.Assertions.assertThat
import org.junit.Assert.*
import org.junit.Test
import java.util.*
import kotlin.reflect.full.primaryConstructor
import kotlin.test.assertFailsWith
class UniqueIdentifierTest {
private companion object {
private const val NAME = "MyName"
private val TEST_UUID: UUID = UUID.fromString("00000000-1111-2222-3333-444444444444")
}
@Test(timeout=300_000)
fun testNewInstance() {
val id = UniqueIdentifier(NAME, TEST_UUID)
assertEquals("${NAME}_$TEST_UUID", id.toString())
assertEquals(NAME, id.externalId)
assertEquals(TEST_UUID, id.id)
}
@Test(timeout=300_000)
fun testPrimaryConstructor() {
val primary = UniqueIdentifier::class.primaryConstructor ?: throw AssertionError("primary constructor missing")
assertThat(primary.call(NAME, TEST_UUID)).isEqualTo(UniqueIdentifier(NAME, TEST_UUID))
}
@Test(timeout=300_000)
fun testConstructors() {
assertEquals(1, UniqueIdentifier::class.constructors.size)
val ex = assertFailsWith<IllegalArgumentException> { UniqueIdentifier::class.constructors.first().call() }
assertThat(ex).hasMessage("Callable expects 2 arguments, but 0 were provided.")
}
}

View File

@ -1,68 +0,0 @@
@file:JvmName("CryptoSignUtils")
package net.corda.deterministic.crypto
import net.corda.core.crypto.*
import net.corda.core.crypto.Crypto.findSignatureScheme
import net.corda.core.crypto.Crypto.isSupportedSignatureScheme
import net.corda.core.serialization.serialize
import java.security.*
/**
* This is a slightly modified copy of signing utils from net.corda.core.crypto.Crypto, which are normally removed from DJVM.
* However, we need those for TransactionSignatureTest.
*/
object CryptoSignUtils {
@JvmStatic
@Throws(InvalidKeyException::class, SignatureException::class)
fun doSign(schemeCodeName: String, privateKey: PrivateKey, clearData: ByteArray): ByteArray {
return doSign(findSignatureScheme(schemeCodeName), privateKey, clearData)
}
/**
* Generic way to sign [ByteArray] data with a [PrivateKey] and a known [Signature].
* @param signatureScheme a [SignatureScheme] object, retrieved from supported signature schemes, see [Crypto].
* @param privateKey the signer's [PrivateKey].
* @param clearData the data/message to be signed in [ByteArray] form (usually the Merkle root).
* @return the digital signature (in [ByteArray]) on the input message.
* @throws IllegalArgumentException if the signature scheme is not supported for this private key.
* @throws InvalidKeyException if the private key is invalid.
* @throws SignatureException if signing is not possible due to malformed data or private key.
*/
@JvmStatic
@Throws(InvalidKeyException::class, SignatureException::class)
fun doSign(signatureScheme: SignatureScheme, privateKey: PrivateKey, clearData: ByteArray): ByteArray {
require(isSupportedSignatureScheme(signatureScheme)) {
"Unsupported key/algorithm for schemeCodeName: ${signatureScheme.schemeCodeName}"
}
require(clearData.isNotEmpty()) { "Signing of an empty array is not permitted!" }
val signature = Signature.getInstance(signatureScheme.signatureName, signatureScheme.providerName)
signature.initSign(privateKey)
signature.update(clearData)
return signature.sign()
}
/**
* Generic way to sign [SignableData] objects with a [PrivateKey].
* [SignableData] is a wrapper over the transaction's id (Merkle root) in order to attach extra information, such as
* a timestamp or partial and blind signature indicators.
* @param keyPair the signer's [KeyPair].
* @param signableData a [SignableData] object that adds extra information to a transaction.
* @return a [TransactionSignature] object than contains the output of a successful signing, signer's public key and
* the signature metadata.
* @throws IllegalArgumentException if the signature scheme is not supported for this private key.
* @throws InvalidKeyException if the private key is invalid.
* @throws SignatureException if signing is not possible due to malformed data or private key.
*/
@JvmStatic
@Throws(InvalidKeyException::class, SignatureException::class)
fun doSign(keyPair: KeyPair, signableData: SignableData): TransactionSignature {
val sigKey: SignatureScheme = findSignatureScheme(keyPair.private)
val sigMetaData: SignatureScheme = findSignatureScheme(keyPair.public)
require(sigKey == sigMetaData) {
"Metadata schemeCodeName: ${sigMetaData.schemeCodeName} is not aligned with the key type: ${sigKey.schemeCodeName}."
}
val signatureBytes = doSign(sigKey.schemeCodeName, keyPair.private, signableData.serialize().bytes)
return TransactionSignature(signatureBytes, keyPair.public, signableData.signatureMetadata)
}
}

View File

@ -1,50 +0,0 @@
package net.corda.deterministic.crypto
import net.corda.core.crypto.DigestService
import net.corda.core.crypto.MerkleTree
import net.corda.core.crypto.SecureHash
import org.junit.Assert.assertEquals
import org.junit.Test
class MerkleTreeTest {
private fun leafs(algorithm : String) : List<SecureHash> =
listOf(SecureHash.allOnesHashFor(algorithm), SecureHash.zeroHashFor(algorithm))
@Test(timeout=300_000)
fun testCreate() {
val merkle = MerkleTree.getMerkleTree(leafs(SecureHash.SHA2_256), DigestService.sha2_256)
assertEquals(SecureHash.create("A5DE9B714ACCD8AFAAABF1CBD6E1014C9D07FF95C2AE154D91EC68485B31E7B5"), merkle.hash)
}
@Test(timeout=300_000)
fun `test create SHA2-384`() {
val merkle = MerkleTree.getMerkleTree(leafs(SecureHash.SHA2_384), DigestService.sha2_384)
assertEquals(SecureHash.create("SHA-384:2B83D37859E3665D7C239964D769CF950EE6478C13E4CA2D6643C23B6C4EAE035C88F654D22E0D65E7CA40BAE4F3718F"), merkle.hash)
}
@Test(timeout=300_000)
fun `test create SHA2-256 to SHA2-384`() {
val merkle = MerkleTree.getMerkleTree(leafs(SecureHash.SHA2_256), DigestService.sha2_384)
assertEquals(SecureHash.create("SHA-384:02A4E8EA5AA4BBAFE80C0E7127B15994B84030BE8616EA2A0127D85203CF34221403635C08084A6BDDB1DB06333F0A49"), merkle.hash)
}
// @Test(timeout=300_000)
// fun testCreateSHA3256() {
// val merkle = MerkleTree.getMerkleTree(listOf(SecureHash.allOnesHashFor(SecureHash.SHA3_256),
// SecureHash.zeroHashFor(SecureHash.SHA3_256)), DigestService.sha3_256)
// assertEquals(SecureHash.create("SHA3-256:80673DBEEC8F6761ACBB121E7E45F61D4279CCD8B8E2231741ECD0716F4C9EDC"), merkle.hash)
// }
//
// @Test(timeout=300_000)
// fun testCreateSHA2256toSHA3256() {
// val merkle = MerkleTree.getMerkleTree(listOf(SecureHash.allOnesHash, SecureHash.zeroHash), DigestService.sha3_256)
// assertEquals(SecureHash.create("SHA3-256:80673DBEEC8F6761ACBB121E7E45F61D4279CCD8B8E2231741ECD0716F4C9EDC"), merkle.hash)
// }
//
// @Test(timeout=300_000)
// fun testCreateSHA3256toSHA2256() {
// val merkle = MerkleTree.getMerkleTree(listOf(SecureHash.allOnesHashFor(SecureHash.SHA3_256),
// SecureHash.zeroHashFor(SecureHash.SHA3_256)), DigestService.sha2_256)
// assertEquals(SecureHash.create("A5DE9B714ACCD8AFAAABF1CBD6E1014C9D07FF95C2AE154D91EC68485B31E7B5"), merkle.hash)
// }
}

View File

@ -1,42 +0,0 @@
package net.corda.deterministic.crypto
import net.corda.core.crypto.SecureHash
import org.bouncycastle.util.encoders.Hex
import org.junit.Assert.*
import org.junit.Test
import java.security.MessageDigest
class SecureHashTest {
@Test(timeout=300_000)
fun testSHA256() {
val hash = SecureHash.sha256(byteArrayOf(0x64, -0x13, 0x42, 0x3a))
assertEquals(SecureHash.create("6D1687C143DF792A011A1E80670A4E4E0C25D0D87A39514409B1ABFC2043581F"), hash)
assertEquals("6D1687C143DF792A011A1E80670A4E4E0C25D0D87A39514409B1ABFC2043581F", hash.toString())
}
@Test(timeout=300_000)
fun testPrefix() {
val data = byteArrayOf(0x7d, 0x03, -0x21, 0x32, 0x56, 0x47)
val digest = data.digestFor("SHA-256")
val prefix = SecureHash.sha256(data).prefixChars(8)
assertEquals(Hex.toHexString(digest).substring(0, 8).toUpperCase(), prefix)
}
@Test(timeout=300_000)
fun testConcat() {
val hash1 = SecureHash.sha256(byteArrayOf(0x7d, 0x03, -0x21, 0x32, 0x56, 0x47))
val hash2 = SecureHash.sha256(byteArrayOf(0x63, 0x01, 0x7f, -0x29, 0x1e, 0x3c))
val combined = hash1.hashConcat(hash2)
assertArrayEquals((hash1.bytes + hash2.bytes).digestFor("SHA-256"), combined.bytes)
}
@Test(timeout=300_000)
fun testConstants() {
assertArrayEquals(SecureHash.zeroHash.bytes, ByteArray(32))
assertArrayEquals(SecureHash.allOnesHash.bytes, ByteArray(32) { 0xFF.toByte() })
}
}
private fun ByteArray.digestFor(algorithm: String): ByteArray {
return MessageDigest.getInstance(algorithm).digest(this)
}

View File

@ -1,22 +0,0 @@
package net.corda.deterministic.crypto
import net.corda.core.crypto.CordaSecurityProvider
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import java.security.NoSuchAlgorithmException
import java.security.SecureRandom
import kotlin.test.assertFailsWith
class SecureRandomTest {
private companion object {
init {
CordaSecurityProvider()
}
}
@Test(timeout=300_000)
fun testNoCordaPRNG() {
val error = assertFailsWith<NoSuchAlgorithmException> { SecureRandom.getInstance("CordaPRNG") }
assertThat(error).hasMessage("CordaPRNG SecureRandom not available")
}
}

View File

@ -1,143 +0,0 @@
package net.corda.deterministic.crypto
import net.corda.core.crypto.*
import net.corda.deterministic.KeyStoreProvider
import net.corda.deterministic.CheatingSecurityProvider
import net.corda.deterministic.verifier.LocalSerializationRule
import org.junit.*
import org.junit.rules.RuleChain
import java.security.*
import kotlin.test.*
class TransactionSignatureTest {
companion object {
private const val KEYSTORE_PASSWORD = "deterministic"
private val testBytes = "12345678901234567890123456789012".toByteArray()
private val keyStoreProvider = KeyStoreProvider("keystore/txsignature.pfx", KEYSTORE_PASSWORD)
private lateinit var keyPair: KeyPair
@ClassRule
@JvmField
val rules: RuleChain = RuleChain.outerRule(LocalSerializationRule(TransactionSignatureTest::class))
.around(keyStoreProvider)
@BeforeClass
@JvmStatic
fun setupClass() {
keyPair = keyStoreProvider.getKeyPair("tx")
}
}
/** Valid sign and verify. */
@Test(timeout=300_000)
fun `Signature metadata full sign and verify`() {
// Create a SignableData object.
val signableData = SignableData(testBytes.sha256(), SignatureMetadata(1, Crypto.findSignatureScheme(keyPair.public).schemeNumberID))
// Sign the meta object.
val transactionSignature: TransactionSignature = CheatingSecurityProvider().use {
CryptoSignUtils.doSign(keyPair, signableData)
}
// Check auto-verification.
assertTrue(transactionSignature.verify(testBytes.sha256()))
// Check manual verification.
assertTrue(Crypto.doVerify(testBytes.sha256(), transactionSignature))
}
/** Verification should fail; corrupted metadata - clearData (Merkle root) has changed. */
@Test(expected = SignatureException::class)
fun `Signature metadata full failure clearData has changed`() {
val signableData = SignableData(testBytes.sha256(), SignatureMetadata(1, Crypto.findSignatureScheme(keyPair.public).schemeNumberID))
val transactionSignature = CheatingSecurityProvider().use {
CryptoSignUtils.doSign(keyPair, signableData)
}
Crypto.doVerify((testBytes + testBytes).sha256(), transactionSignature)
}
@Test(timeout=300_000)
fun `Verify multi-tx signature`() {
// Deterministically create 5 txIds.
val txIds: List<SecureHash> = IntRange(0, 4).map { byteArrayOf(it.toByte()).sha256() }
// Multi-tx signature.
val txSignature = signMultipleTx(txIds, keyPair)
// The hash of all txIds are used as leaves.
val merkleTree = MerkleTree.getMerkleTree(txIds.map { it.sha256() }, DigestService.default)
// We haven't added the partial tree yet.
assertNull(txSignature.partialMerkleTree)
// Because partial tree is still null, but we signed over a block of txs, verifying a single tx will fail.
assertFailsWith<SignatureException> { Crypto.doVerify(txIds[3], txSignature) }
// Create a partial tree for one tx.
val pmt = PartialMerkleTree.build(merkleTree, listOf(txIds[0].sha256()))
// Add the partial Merkle tree to the tx signature.
val txSignatureWithTree = TransactionSignature(txSignature.bytes, txSignature.by, txSignature.signatureMetadata, pmt)
// Verify the corresponding txId with every possible way.
assertTrue(Crypto.doVerify(txIds[0], txSignatureWithTree))
assertTrue(txSignatureWithTree.verify(txIds[0]))
assertTrue(Crypto.isValid(txIds[0], txSignatureWithTree))
assertTrue(txSignatureWithTree.isValid(txIds[0]))
// Verify the rest txs in the block, which are not included in the partial Merkle tree.
txIds.subList(1, txIds.size).forEach {
assertFailsWith<IllegalArgumentException> { Crypto.doVerify(it, txSignatureWithTree) }
}
// Test that the Merkle tree consists of hash(txId), not txId.
assertFailsWith<MerkleTreeException> { PartialMerkleTree.build(merkleTree, listOf(txIds[0])) }
// What if we send the Full tree. This could be used if notaries didn't want to create a per tx partial tree.
// Create a partial tree for all txs, thus all leaves are included.
val pmtFull = PartialMerkleTree.build(merkleTree, txIds.map { it.sha256() })
// Add the partial Merkle tree to the tx.
val txSignatureWithFullTree = TransactionSignature(txSignature.bytes, txSignature.by, txSignature.signatureMetadata, pmtFull)
// All txs can be verified, as they are all included in the provided partial tree.
txIds.forEach {
assertTrue(Crypto.doVerify(it, txSignatureWithFullTree))
}
}
@Test(timeout=300_000)
fun `Verify one-tx signature`() {
val txId = "aTransaction".toByteArray().sha256()
// One-tx signature.
val txSignature = try {
signOneTx(txId, keyPair)
} catch (e: Throwable) {
e.cause?.printStackTrace()
throw e
}
// partialMerkleTree should be null.
assertNull(txSignature.partialMerkleTree)
// Verify the corresponding txId with every possible way.
assertTrue(Crypto.doVerify(txId, txSignature))
assertTrue(txSignature.verify(txId))
assertTrue(Crypto.isValid(txId, txSignature))
assertTrue(txSignature.isValid(txId))
// We signed the txId itself, not its hash (because it was a signature over one tx only and no partial tree has been received).
assertFailsWith<SignatureException> { Crypto.doVerify(txId.sha256(), txSignature) }
}
// Returns a TransactionSignature over the Merkle root, but the partial tree is null.
private fun signMultipleTx(txIds: List<SecureHash>, keyPair: KeyPair): TransactionSignature {
val merkleTreeRoot = MerkleTree.getMerkleTree(txIds.map { it.sha256() }, DigestService.default).hash
return signOneTx(merkleTreeRoot, keyPair)
}
// Returns a TransactionSignature over one SecureHash.
// Note that if one tx is to be signed, we don't create a Merkle tree and we directly sign over the txId.
private fun signOneTx(txId: SecureHash, keyPair: KeyPair): TransactionSignature {
val signableData = SignableData(txId, SignatureMetadata(3, Crypto.findSignatureScheme(keyPair.public).schemeNumberID))
return CheatingSecurityProvider().use {
CryptoSignUtils.doSign(keyPair, signableData)
}
}
}

View File

@ -1,30 +0,0 @@
package net.corda.deterministic.transactions
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.TransactionSignature
import net.corda.core.transactions.TransactionWithSignatures
import org.junit.Test
import java.security.PublicKey
class TransactionWithSignaturesTest {
@Test(timeout=300_000)
fun txWithSigs() {
val tx = object : TransactionWithSignatures {
override val id: SecureHash
get() = SecureHash.zeroHash
override val requiredSigningKeys: Set<PublicKey>
get() = emptySet()
override val sigs: List<TransactionSignature>
get() = emptyList()
override fun getKeyDescriptions(keys: Set<PublicKey>): List<String> {
return emptyList()
}
}
tx.verifyRequiredSignatures()
tx.checkSignaturesAreValid()
tx.getMissingSigners()
tx.verifySignaturesExcept()
tx.verifySignaturesExcept(emptySet())
}
}

View File

@ -1,29 +0,0 @@
package net.corda.deterministic.txverify
import net.corda.deterministic.bytesOfResource
import net.corda.deterministic.verifier.LocalSerializationRule
import net.corda.deterministic.verifier.verifyTransaction
import net.corda.finance.contracts.asset.Cash.Commands.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.ClassRule
import org.junit.Test
import kotlin.test.assertFailsWith
class VerifyTransactionTest {
companion object {
@ClassRule
@JvmField
val serialization = LocalSerializationRule(VerifyTransactionTest::class)
}
@Test(timeout=300_000)
fun success() {
verifyTransaction(bytesOfResource("txverify/tx-success.bin"))
}
@Test(timeout=300_000)
fun failure() {
val e = assertFailsWith<Exception> { verifyTransaction(bytesOfResource("txverify/tx-failure.bin")) }
assertThat(e).hasMessageContaining("Required ${Move::class.java.canonicalName} command")
}
}

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout pattern="%date %highlight{%level %c{1}.%method - %msg%n}{INFO=white,WARN=red,FATAL=bright red}"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console-Appender"/>
</Root>
</Loggers>
</Configuration>

View File

@ -1,56 +0,0 @@
plugins {
id 'java-library'
id 'net.corda.plugins.publish-utils'
id 'com.jfrog.artifactory'
id 'idea'
}
apply from: "${rootProject.projectDir}/deterministic.gradle"
description 'Test utilities for deterministic contract verification'
configurations {
deterministicArtifacts {
canBeResolved = false
}
// Compile against the deterministic artifacts to ensure that we use only the deterministic API subset.
compileOnly.extendsFrom deterministicArtifacts
runtimeArtifacts.extendsFrom api
}
dependencies {
deterministicArtifacts project(path: ':serialization-deterministic', configuration: 'deterministicArtifacts')
deterministicArtifacts project(path: ':core-deterministic', configuration: 'deterministicArtifacts')
runtimeArtifacts project(':serialization')
runtimeArtifacts project(':core')
api "junit:junit:$junit_version"
runtimeOnly "org.junit.vintage:junit-vintage-engine:$junit_vintage_version"
}
jar {
archiveBaseName = 'corda-deterministic-verifier'
}
artifacts {
deterministicArtifacts jar
runtimeArtifacts jar
publish jar
}
publish {
// Our published POM will contain dependencies on the non-deterministic Corda artifacts.
dependenciesFrom(configurations.runtimeArtifacts) {
defaultScope = 'compile'
}
name jar.archiveBaseName.get()
}
idea {
module {
if (project.hasProperty("deterministic_idea_sdk")) {
jdkName project.property("deterministic_idea_sdk") as String
}
}
}

View File

@ -1,82 +0,0 @@
package net.corda.deterministic.verifier
import net.corda.core.serialization.SerializationContext
import net.corda.core.serialization.SerializationContext.UseCase.P2P
import net.corda.core.serialization.SerializationCustomSerializer
import net.corda.core.serialization.SerializationWhitelist
import net.corda.core.serialization.internal.SerializationEnvironment
import net.corda.core.serialization.internal._driverSerializationEnv
import net.corda.serialization.internal.*
import net.corda.serialization.internal.amqp.*
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
import kotlin.reflect.KClass
import kotlin.reflect.jvm.jvmName
class LocalSerializationRule(private val label: String) : TestRule {
constructor(klass: KClass<*>) : this(klass.jvmName)
private companion object {
private val AMQP_P2P_CONTEXT = SerializationContextImpl(
amqpMagic,
LocalSerializationRule::class.java.classLoader,
GlobalTransientClassWhiteList(BuiltInExceptionsWhitelist()),
emptyMap(),
true,
P2P,
null
)
}
override fun apply(base: Statement, description: Description): Statement {
return object : Statement() {
override fun evaluate() {
init()
try {
base.evaluate()
} finally {
clear()
}
}
}
}
fun reset() {
clear()
init()
}
private fun init() {
_driverSerializationEnv.set(createTestSerializationEnv())
}
private fun clear() {
_driverSerializationEnv.set(null)
}
private fun createTestSerializationEnv(): SerializationEnvironment {
val factory = SerializationFactoryImpl(mutableMapOf()).apply {
registerScheme(AMQPSerializationScheme(emptySet(), emptySet(), AccessOrderLinkedHashMap(128)))
}
return SerializationEnvironment.with(factory, AMQP_P2P_CONTEXT)
}
private class AMQPSerializationScheme(
cordappCustomSerializers: Set<SerializationCustomSerializer<*, *>>,
cordappSerializationWhitelists: Set<SerializationWhitelist>,
serializerFactoriesForContexts: AccessOrderLinkedHashMap<SerializationFactoryCacheKey, SerializerFactory>
) : AbstractAMQPSerializationScheme(cordappCustomSerializers, cordappSerializationWhitelists, serializerFactoriesForContexts) {
override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory {
throw UnsupportedOperationException()
}
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
throw UnsupportedOperationException()
}
override fun canDeserializeVersion(magic: CordaSerializationMagic, target: SerializationContext.UseCase): Boolean {
return canDeserializeVersion(magic) && target == P2P
}
}
}

View File

@ -1,19 +0,0 @@
package net.corda.deterministic.verifier
import net.corda.core.contracts.ContractClassName
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.Party
import net.corda.core.internal.AbstractAttachment
import net.corda.core.serialization.CordaSerializable
import java.security.PublicKey
// A valid zip file with 1 entry.
val simpleZip = byteArrayOf(80, 75, 3, 4, 20, 0, 8, 8, 8, 0, 15, 113, 79, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 47, 97, -2, -54, 0, 0, 75, 4, 0, 80, 75, 7, 8, 67, -66, -73, -24, 3, 0, 0, 0, 1, 0, 0, 0, 80, 75, 1, 2, 20, 0, 20, 0, 8, 8, 8, 0, 15, 113, 79, 78, 67, -66, -73, -24, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 97, -2, -54, 0, 0, 80, 75, 5, 6, 0, 0, 0, 0, 1, 0, 1, 0, 52, 0, 0, 0, 55, 0, 0, 0, 0, 0)
@CordaSerializable
class MockContractAttachment(
override val id: SecureHash = SecureHash.zeroHash,
val contract: ContractClassName,
override val signerKeys: List<PublicKey> = emptyList(),
override val signers: List<Party> = emptyList()
) : AbstractAttachment({ simpleZip }, "app")

View File

@ -1,6 +0,0 @@
@file:JvmName("SampleData")
package net.corda.deterministic.verifier
import net.corda.core.contracts.TypeOnlyCommandData
object SampleCommandData : TypeOnlyCommandData()

View File

@ -1,35 +0,0 @@
package net.corda.deterministic.verifier
import net.corda.core.contracts.Attachment
import net.corda.core.contracts.ContractAttachment
import net.corda.core.internal.DEPLOYED_CORDAPP_UPLOADER
import net.corda.core.internal.toLtxDjvmInternal
import net.corda.core.node.NetworkParameters
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.deserialize
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.WireTransaction
@Suppress("MemberVisibilityCanBePrivate")
//TODO the use of deprecated toLedgerTransaction need to be revisited as resolveContractAttachment requires attachments of the transactions which created input states...
//TODO ...to check contract version non downgrade rule, currently dummy Attachment if not fund is used which sets contract version to '1'
@CordaSerializable
class TransactionVerificationRequest(val wtxToVerify: SerializedBytes<WireTransaction>,
val dependencies: Array<SerializedBytes<WireTransaction>>,
val attachments: Array<ByteArray>,
val networkParameters: SerializedBytes<NetworkParameters>) {
fun toLedgerTransaction(): LedgerTransaction {
val deps = dependencies.map { it.deserialize() }.associateBy(WireTransaction::id)
val attachments = attachments.map { it.deserialize<Attachment>() }
val attachmentMap = attachments
.mapNotNull { it as? MockContractAttachment }
.associateBy(Attachment::id) { ContractAttachment(it, it.contract, uploader = DEPLOYED_CORDAPP_UPLOADER) }
@Suppress("DEPRECATION")
return wtxToVerify.deserialize().toLtxDjvmInternal(
resolveAttachment = { attachmentMap[it] },
resolveStateRef = { deps[it.txhash]?.outputs?.get(it.index) },
resolveParameters = { networkParameters.deserialize() }
)
}
}

View File

@ -1,21 +0,0 @@
@file:JvmName("Verifier")
package net.corda.deterministic.verifier
import net.corda.core.serialization.deserialize
import net.corda.core.transactions.LedgerTransaction
/**
* We assume the signatures were already checked outside the sandbox: the purpose of this code
* is simply to check the sensitive, app-specific parts of a transaction.
*
* TODO: Transaction data is meant to be encrypted under an enclave-private key.
*/
@Throws(Exception::class)
fun verifyTransaction(reqBytes: ByteArray) {
deserialize(reqBytes).verify()
}
private fun deserialize(reqBytes: ByteArray): LedgerTransaction {
return reqBytes.deserialize<TransactionVerificationRequest>()
.toLedgerTransaction()
}

View File

@ -92,6 +92,8 @@ dependencies {
smokeTestCompile project(':smoke-test-utils') smokeTestCompile project(':smoke-test-utils')
smokeTestCompile "org.assertj:assertj-core:${assertj_version}" smokeTestCompile "org.assertj:assertj-core:${assertj_version}"
// used by FinalityFlowTests
testCompile project(':testing:cordapps:cashobservers')
} }
configurations { configurations {

View File

@ -10,6 +10,7 @@ import net.corda.core.crypto.SecureHash.Companion.allOnesHash
import net.corda.core.crypto.SecureHash.Companion.zeroHash import net.corda.core.crypto.SecureHash.Companion.zeroHash
import net.corda.core.crypto.SignableData import net.corda.core.crypto.SignableData
import net.corda.core.crypto.SignatureMetadata import net.corda.core.crypto.SignatureMetadata
import net.corda.core.crypto.sign
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.canBeTransitionedFrom import net.corda.core.internal.canBeTransitionedFrom
@ -49,6 +50,7 @@ class ConstraintsPropagationTests {
val testSerialization = SerializationEnvironmentRule() val testSerialization = SerializationEnvironmentRule()
private companion object { private companion object {
val DUMMY_NOTARY_IDENTITY = TestIdentity(DUMMY_NOTARY_NAME, 20)
val DUMMY_NOTARY = TestIdentity(DUMMY_NOTARY_NAME, 20).party val DUMMY_NOTARY = TestIdentity(DUMMY_NOTARY_NAME, 20).party
val ALICE = TestIdentity(CordaX500Name("ALICE", "London", "GB")) val ALICE = TestIdentity(CordaX500Name("ALICE", "London", "GB"))
val ALICE_PARTY get() = ALICE.party val ALICE_PARTY get() = ALICE.party
@ -376,7 +378,8 @@ class ConstraintsPropagationTests {
requireSupportedHashType(wireTransaction) requireSupportedHashType(wireTransaction)
val nodeKey = ALICE_PUBKEY val nodeKey = ALICE_PUBKEY
val sigs = listOf(keyManagementService.sign( val sigs = listOf(keyManagementService.sign(
SignableData(wireTransaction.id, SignatureMetadata(4, Crypto.findSignatureScheme(nodeKey).schemeNumberID)), nodeKey)) SignableData(wireTransaction.id, SignatureMetadata(4, Crypto.findSignatureScheme(nodeKey).schemeNumberID)), nodeKey),
DUMMY_NOTARY_IDENTITY.keyPair.sign(SignableData(wireTransaction.id, SignatureMetadata(4, Crypto.findSignatureScheme(DUMMY_NOTARY_IDENTITY.publicKey).schemeNumberID))))
recordTransactions(SignedTransaction(wireTransaction, sigs)) recordTransactions(SignedTransaction(wireTransaction, sigs))
} }

View File

@ -30,7 +30,7 @@ import java.util.*
class ContractUpgradeFlowTest : WithContracts, WithFinality { class ContractUpgradeFlowTest : WithContracts, WithFinality {
companion object { companion object {
private val classMockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP, DUMMY_CONTRACTS_CORDAPP, enclosedCordapp())) private val classMockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP, DUMMY_CONTRACTS_CORDAPP, enclosedCordapp()))
@JvmStatic @JvmStatic
@AfterClass @AfterClass

View File

@ -1,32 +1,95 @@
package net.corda.coretests.flows package net.corda.coretests.flows
import co.paralleluniverse.fibers.Suspendable
import com.natpryce.hamkrest.and import com.natpryce.hamkrest.and
import com.natpryce.hamkrest.assertion.assertThat import com.natpryce.hamkrest.assertion.assertThat
import net.corda.core.contracts.Amount
import net.corda.core.contracts.PartyAndReference
import net.corda.core.contracts.StateAndContract
import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.TransactionVerificationException
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.TransactionSignature
import net.corda.core.flows.FinalityFlow import net.corda.core.flows.FinalityFlow
import net.corda.core.flows.FlowException
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowSession
import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.NotaryError
import net.corda.core.flows.NotaryException
import net.corda.core.flows.NotarySigCheck
import net.corda.core.flows.ReceiveFinalityFlow
import net.corda.core.flows.ReceiveTransactionFlow
import net.corda.core.flows.ReceiverDistributionRecord
import net.corda.core.flows.SendTransactionFlow
import net.corda.core.flows.SenderDistributionRecord
import net.corda.core.flows.StartableByRPC
import net.corda.core.flows.TransactionStatus
import net.corda.core.flows.UnexpectedFlowEndException
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.FetchDataFlow
import net.corda.core.internal.PLATFORM_VERSION
import net.corda.core.internal.PlatformVersionSwitches
import net.corda.core.internal.ServiceHubCoreInternal
import net.corda.core.node.StatesToRecord
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.coretests.flows.WithFinality.FinalityInvoker import net.corda.core.utilities.unwrap
import net.corda.finance.POUNDS
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.issuedBy
import net.corda.testing.core.*
import net.corda.coretesting.internal.matchers.flow.willReturn import net.corda.coretesting.internal.matchers.flow.willReturn
import net.corda.coretesting.internal.matchers.flow.willThrow import net.corda.coretesting.internal.matchers.flow.willThrow
import net.corda.testing.node.internal.* import net.corda.coretests.flows.WithFinality.FinalityInvoker
import net.corda.coretests.flows.WithFinality.OldFinalityInvoker
import net.corda.finance.GBP
import net.corda.finance.POUNDS
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
import net.corda.finance.issuedBy
import net.corda.finance.test.flows.CashIssueWithObserversFlow
import net.corda.finance.test.flows.CashPaymentWithObserversFlow
import net.corda.node.services.persistence.DBTransactionStorage
import net.corda.node.services.persistence.DBTransactionStorageLedgerRecovery.DBReceiverDistributionRecord
import net.corda.node.services.persistence.DBTransactionStorageLedgerRecovery.DBSenderDistributionRecord
import net.corda.node.services.persistence.HashedDistributionList
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.CHARLIE_NAME
import net.corda.testing.core.TestIdentity
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.FINANCE_WORKFLOWS_CORDAPP
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.InternalMockNodeParameters
import net.corda.testing.node.internal.MOCK_VERSION_INFO
import net.corda.testing.node.internal.TestCordappInternal
import net.corda.testing.node.internal.TestStartedNode
import net.corda.testing.node.internal.cordappWithPackages
import net.corda.testing.node.internal.enclosedCordapp
import net.corda.testing.node.internal.findCordapp
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.After import org.junit.After
import org.junit.Assert.assertNotNull
import org.junit.Test import org.junit.Test
import java.sql.SQLException
import java.util.Random
import kotlin.test.assertEquals
import kotlin.test.assertNull
import kotlin.test.fail
class FinalityFlowTests : WithFinality { class FinalityFlowTests : WithFinality {
companion object { companion object {
private val CHARLIE = TestIdentity(CHARLIE_NAME, 90).party private val CHARLIE = TestIdentity(CHARLIE_NAME, 90).party
} }
override val mockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP, enclosedCordapp(), override val mockNet = InternalMockNetwork(cordappsForAllNodes = setOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP, DUMMY_CONTRACTS_CORDAPP, enclosedCordapp(),
CustomCordapp(targetPlatformVersion = 3, classes = setOf(FinalityFlow::class.java)))) findCordapp("net.corda.finance.test.flows")))
private val aliceNode = makeNode(ALICE_NAME) private val aliceNode = makeNode(ALICE_NAME)
private val notary = mockNet.defaultNotaryIdentity private val notary = mockNet.defaultNotaryIdentity
@ -60,9 +123,8 @@ class FinalityFlowTests : WithFinality {
fun `allow use of the old API if the CorDapp target version is 3`() { fun `allow use of the old API if the CorDapp target version is 3`() {
val oldBob = createBob(cordapps = listOf(tokenOldCordapp())) val oldBob = createBob(cordapps = listOf(tokenOldCordapp()))
val stx = aliceNode.issuesCashTo(oldBob) val stx = aliceNode.issuesCashTo(oldBob)
@Suppress("DEPRECATION") aliceNode.startFlowAndRunNetwork(OldFinalityInvoker(stx)).resultFuture.getOrThrow()
aliceNode.startFlowAndRunNetwork(FinalityFlow(stx)).resultFuture.getOrThrow() assertThat(oldBob.services.validatedTransactions.getTransaction(stx.id)).isNotNull
assertThat(oldBob.services.validatedTransactions.getTransaction(stx.id)).isNotNull()
} }
@Test(timeout=300_000) @Test(timeout=300_000)
@ -76,12 +138,497 @@ class FinalityFlowTests : WithFinality {
oldRecipients = setOf(oldBob.info.singleIdentity()) oldRecipients = setOf(oldBob.info.singleIdentity())
)).resultFuture )).resultFuture
resultFuture.getOrThrow() resultFuture.getOrThrow()
assertThat(newCharlie.services.validatedTransactions.getTransaction(stx.id)).isNotNull() assertThat(newCharlie.services.validatedTransactions.getTransaction(stx.id)).isNotNull
assertThat(oldBob.services.validatedTransactions.getTransaction(stx.id)).isNotNull() assertThat(oldBob.services.validatedTransactions.getTransaction(stx.id)).isNotNull
} }
private fun createBob(cordapps: List<TestCordappInternal> = emptyList()): TestStartedNode { @Test(timeout=300_000)
return mockNet.createNode(InternalMockNodeParameters(legalName = BOB_NAME, additionalCordapps = cordapps)) fun `two phase finality flow transaction`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY)
val stx = aliceNode.startFlow(CashIssueFlow(Amount(1000L, GBP), OpaqueBytes.of(1), notary)).resultFuture.getOrThrow().stx
aliceNode.startFlowAndRunNetwork(CashPaymentFlow(Amount(100, GBP), bobNode.info.singleIdentity())).resultFuture.getOrThrow()
assertThat(aliceNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
assertThat(bobNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
}
@Test(timeout=300_000)
fun `two phase finality flow initiator to pre-2PF peer`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY - 1)
val stx = aliceNode.startFlow(CashIssueFlow(Amount(1000L, GBP), OpaqueBytes.of(1), notary)).resultFuture.getOrThrow().stx
aliceNode.startFlowAndRunNetwork(CashPaymentFlow(Amount(100, GBP), bobNode.info.singleIdentity())).resultFuture.getOrThrow()
assertThat(aliceNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
assertThat(bobNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
}
@Test(timeout=300_000)
fun `pre-2PF initiator to two phase finality flow peer`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY - 1)
val stx = bobNode.startFlow(CashIssueFlow(Amount(1000L, GBP), OpaqueBytes.of(1), notary)).resultFuture.getOrThrow().stx
bobNode.startFlowAndRunNetwork(CashPaymentFlow(Amount(100, GBP), aliceNode.info.singleIdentity())).resultFuture.getOrThrow()
assertThat(aliceNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
assertThat(bobNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
}
@Test(timeout=300_000)
fun `two phase finality flow double spend transaction`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY)
val ref = aliceNode.startFlowAndRunNetwork(IssueFlow(notary)).resultFuture.getOrThrow()
val stx = aliceNode.startFlowAndRunNetwork(SpendFlow(ref, bobNode.info.singleIdentity())).resultFuture.getOrThrow()
val (_, txnStatusAlice) = aliceNode.services.validatedTransactions.getTransactionInternal(stx.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusAlice)
val (_, txnStatusBob) = bobNode.services.validatedTransactions.getTransactionInternal(stx.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusBob)
try {
aliceNode.startFlowAndRunNetwork(SpendFlow(ref, bobNode.info.singleIdentity())).resultFuture.getOrThrow()
}
catch (e: NotaryException) {
val stxId = (e.error as NotaryError.Conflict).txId
assertNull(aliceNode.services.validatedTransactions.getTransactionInternal(stxId))
// Note: double spend error not propagated to peers by default (corDapp PV = 3)
// Un-notarised txn clean-up occurs in ReceiveFinalityFlow upon receipt of UnexpectedFlowEndException
assertNull(aliceNode.services.validatedTransactions.getTransactionInternal(stxId))
assertTxnRemovedFromDatabase(aliceNode, stxId)
}
}
@Test(timeout=300_000)
fun `two phase finality flow double spend transaction with double spend handling`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY)
val ref = aliceNode.startFlowAndRunNetwork(IssueFlow(notary)).resultFuture.getOrThrow()
val stx = aliceNode.startFlowAndRunNetwork(SpendFlow(ref, bobNode.info.singleIdentity())).resultFuture.getOrThrow()
val (_, txnStatusAlice) = aliceNode.services.validatedTransactions.getTransactionInternal(stx.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusAlice)
val (_, txnStatusBob) = bobNode.services.validatedTransactions.getTransactionInternal(stx.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusBob)
try {
aliceNode.startFlowAndRunNetwork(SpendFlow(ref, bobNode.info.singleIdentity(), handlePropagatedNotaryError = true)).resultFuture.getOrThrow()
}
catch (e: NotaryException) {
val stxId = (e.error as NotaryError.Conflict).txId
assertNull(aliceNode.services.validatedTransactions.getTransactionInternal(stxId))
assertTxnRemovedFromDatabase(aliceNode, stxId)
assertNull(bobNode.services.validatedTransactions.getTransactionInternal(stxId))
assertTxnRemovedFromDatabase(bobNode, stxId)
}
try {
aliceNode.startFlowAndRunNetwork(SpendFlow(ref, bobNode.info.singleIdentity(), handlePropagatedNotaryError = false)).resultFuture.getOrThrow()
}
catch (e: NotaryException) {
val stxId = (e.error as NotaryError.Conflict).txId
assertNull(aliceNode.services.validatedTransactions.getTransactionInternal(stxId))
assertTxnRemovedFromDatabase(aliceNode, stxId)
val (_, txnStatus) = bobNode.services.validatedTransactions.getTransactionInternal(stxId) ?: fail()
assertEquals(TransactionStatus.IN_FLIGHT, txnStatus)
}
}
private fun assertTxnRemovedFromDatabase(node: TestStartedNode, stxId: SecureHash) {
val fromDb = node.database.transaction {
session.createQuery(
"from ${DBTransactionStorage.DBTransaction::class.java.name} where tx_id = :transactionId",
DBTransactionStorage.DBTransaction::class.java
).setParameter("transactionId", stxId.toString()).resultList
}
assertEquals(0, fromDb.size)
}
@Test(timeout=300_000)
fun `two phase finality flow double spend transaction from pre-2PF initiator`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY - 1)
val ref = bobNode.startFlowAndRunNetwork(IssueFlow(notary)).resultFuture.getOrThrow()
val stx = bobNode.startFlowAndRunNetwork(SpendFlow(ref, aliceNode.info.singleIdentity())).resultFuture.getOrThrow()
val (_, txnStatusAlice) = aliceNode.services.validatedTransactions.getTransactionInternal(stx.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusAlice)
val (_, txnStatusBob) = bobNode.services.validatedTransactions.getTransactionInternal(stx.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusBob)
try {
bobNode.startFlowAndRunNetwork(SpendFlow(ref, aliceNode.info.singleIdentity())).resultFuture.getOrThrow()
}
catch (e: NotaryException) {
val stxId = (e.error as NotaryError.Conflict).txId
assertNull(bobNode.services.validatedTransactions.getTransactionInternal(stxId))
assertTxnRemovedFromDatabase(bobNode, stxId)
assertNull(aliceNode.services.validatedTransactions.getTransactionInternal(stxId))
assertTxnRemovedFromDatabase(aliceNode, stxId)
}
}
@Test(timeout=300_000)
fun `two phase finality flow double spend transaction to pre-2PF peer`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY - 1)
val ref = aliceNode.startFlowAndRunNetwork(IssueFlow(notary)).resultFuture.getOrThrow()
val stx = aliceNode.startFlowAndRunNetwork(SpendFlow(ref, bobNode.info.singleIdentity())).resultFuture.getOrThrow()
val (_, txnStatusAlice) = aliceNode.services.validatedTransactions.getTransactionInternal(stx.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusAlice)
val (_, txnStatusBob) = bobNode.services.validatedTransactions.getTransactionInternal(stx.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusBob)
try {
aliceNode.startFlowAndRunNetwork(SpendFlow(ref, bobNode.info.singleIdentity())).resultFuture.getOrThrow()
}
catch (e: NotaryException) {
val stxId = (e.error as NotaryError.Conflict).txId
assertNull(aliceNode.services.validatedTransactions.getTransactionInternal(stxId))
assertTxnRemovedFromDatabase(aliceNode, stxId)
assertNull(bobNode.services.validatedTransactions.getTransactionInternal(stxId))
assertTxnRemovedFromDatabase(bobNode, stxId)
}
}
@Test(timeout=300_000)
fun `two phase finality flow speedy spender`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY)
val ref = aliceNode.startFlowAndRunNetwork(IssueFlow(notary)).resultFuture.getOrThrow()
val notarisedStxn1 = aliceNode.startFlowAndRunNetwork(SpeedySpendFlow(ref, bobNode.info.singleIdentity())).resultFuture.getOrThrow()
val (_, txnStatusAlice) = aliceNode.services.validatedTransactions.getTransactionInternal(notarisedStxn1.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusAlice)
val (_, txnStatusBob) = bobNode.services.validatedTransactions.getTransactionInternal(notarisedStxn1.id) ?: fail()
assertEquals(TransactionStatus.IN_FLIGHT, txnStatusBob)
// now lets attempt a new spend with the new output of the previous transaction
val newStateRef = notarisedStxn1.coreTransaction.outRef<DummyContract.SingleOwnerState>(1)
val notarisedStxn2 = aliceNode.startFlowAndRunNetwork(SpeedySpendFlow(newStateRef, bobNode.info.singleIdentity())).resultFuture.getOrThrow()
// the original transaction is now finalised at Bob (despite the original flow not completing) because Bob resolved the
// original transaction from Alice in the second transaction (and Alice had already notarised and finalised the original transaction)
val (_, txnStatusBobAgain) = bobNode.services.validatedTransactions.getTransactionInternal(notarisedStxn1.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusBobAgain)
val (_, txnStatusAlice2) = aliceNode.services.validatedTransactions.getTransactionInternal(notarisedStxn2.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusAlice2)
val (_, txnStatusBob2) = bobNode.services.validatedTransactions.getTransactionInternal(notarisedStxn2.id) ?: fail()
assertEquals(TransactionStatus.IN_FLIGHT, txnStatusBob2)
// Validate attempt at flow finalisation by Bob has no effect on outcome.
val finaliseStxn1 = bobNode.startFlowAndRunNetwork(FinaliseSpeedySpendFlow(notarisedStxn1.id, notarisedStxn1.sigs)).resultFuture.getOrThrow()
val (_, txnStatusBobYetAgain) = bobNode.services.validatedTransactions.getTransactionInternal(finaliseStxn1.id) ?: fail()
assertEquals(TransactionStatus.VERIFIED, txnStatusBobYetAgain)
}
@Test(timeout=300_000)
fun `two phase finality flow keeps un-notarised transaction where initiator fails to send notary signature`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY)
val ref = aliceNode.startFlowAndRunNetwork(IssueFlow(notary)).resultFuture.getOrThrow()
try {
aliceNode.startFlowAndRunNetwork(MimicFinalityFailureFlow(ref, bobNode.info.singleIdentity())).resultFuture.getOrThrow()
}
catch (e: UnexpectedFlowEndException) {
val stxId = SecureHash.parse(e.message)
val (_, txnStatusBob) = bobNode.services.validatedTransactions.getTransactionInternal(stxId) ?: fail()
assertEquals(TransactionStatus.IN_FLIGHT, txnStatusBob)
}
}
@Test(timeout=300_000)
fun `two phase finality flow issuance transaction with observers`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY)
val stx = aliceNode.startFlowAndRunNetwork(CashIssueWithObserversFlow(
Amount(1000L, GBP), OpaqueBytes.of(1), notary,
observers = setOf(bobNode.info.singleIdentity()))).resultFuture.getOrThrow().stx
assertThat(aliceNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
assertThat(bobNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
val sdrs = getSenderRecoveryData(stx.id, aliceNode.database).apply {
assertEquals(1, this.size)
assertEquals(StatesToRecord.ONLY_RELEVANT, this[0].senderStatesToRecord)
assertEquals(StatesToRecord.ALL_VISIBLE, this[0].receiverStatesToRecord)
assertEquals(SecureHash.sha256(BOB_NAME.toString()), this[0].peerPartyId)
}
val rdr = getReceiverRecoveryData(stx.id, bobNode).apply {
assertNotNull(this)
val hashedDL = HashedDistributionList.decrypt(this!!.encryptedDistributionList.bytes, aliceNode.internals.encryptionService)
assertEquals(StatesToRecord.ONLY_RELEVANT, hashedDL.senderStatesToRecord)
assertEquals(SecureHash.sha256(aliceNode.info.singleIdentity().name.toString()), this.peerPartyId)
assertEquals(mapOf<SecureHash, StatesToRecord>(SecureHash.sha256(BOB_NAME.toString()) to StatesToRecord.ALL_VISIBLE), hashedDL.peerHashToStatesToRecord)
}
validateSenderAndReceiverTimestamps(sdrs, rdr!!)
}
@Test(timeout=300_000)
fun `two phase finality flow payment transaction with observers`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY)
val charlieNode = createNode(CHARLIE_NAME, platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY)
// issue some cash
aliceNode.startFlow(CashIssueFlow(Amount(1000L, GBP), OpaqueBytes.of(1), notary)).resultFuture.getOrThrow().stx
// standard issuance with observers passed in as FinalityFlow sessions
val stx = aliceNode.startFlowAndRunNetwork(CashPaymentWithObserversFlow(
amount = Amount(100L, GBP),
recipient = bobNode.info.singleIdentity(),
observers = setOf(charlieNode.info.singleIdentity()))).resultFuture.getOrThrow()
assertThat(aliceNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
assertThat(bobNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
assertThat(charlieNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
val sdrs = getSenderRecoveryData(stx.id, aliceNode.database).apply {
assertEquals(2, this.size)
assertEquals(StatesToRecord.ONLY_RELEVANT, this[0].senderStatesToRecord)
assertEquals(SecureHash.sha256(BOB_NAME.toString()), this[0].peerPartyId)
assertEquals(StatesToRecord.ALL_VISIBLE, this[1].receiverStatesToRecord)
assertEquals(SecureHash.sha256(CHARLIE_NAME.toString()), this[1].peerPartyId)
}
val rdr = getReceiverRecoveryData(stx.id, bobNode).apply {
assertNotNull(this)
val hashedDL = HashedDistributionList.decrypt(this!!.encryptedDistributionList.bytes, aliceNode.internals.encryptionService)
assertEquals(StatesToRecord.ONLY_RELEVANT, hashedDL.senderStatesToRecord)
assertEquals(SecureHash.sha256(aliceNode.info.singleIdentity().name.toString()), this.peerPartyId)
// note: Charlie assertion here is using the hinted StatesToRecord value passed to it from Alice
assertEquals(mapOf<SecureHash, StatesToRecord>(
SecureHash.sha256(BOB_NAME.toString()) to StatesToRecord.ONLY_RELEVANT,
SecureHash.sha256(CHARLIE_NAME.toString()) to StatesToRecord.ALL_VISIBLE
), hashedDL.peerHashToStatesToRecord)
}
validateSenderAndReceiverTimestamps(sdrs, rdr!!)
// exercise the new FinalityFlow observerSessions constructor parameter
val stx3 = aliceNode.startFlowAndRunNetwork(CashPaymentWithObserversFlow(
amount = Amount(100L, GBP),
recipient = bobNode.info.singleIdentity(),
observers = setOf(charlieNode.info.singleIdentity()),
useObserverSessions = true)).resultFuture.getOrThrow()
assertThat(aliceNode.services.validatedTransactions.getTransaction(stx3.id)).isNotNull
assertThat(bobNode.services.validatedTransactions.getTransaction(stx3.id)).isNotNull
assertThat(charlieNode.services.validatedTransactions.getTransaction(stx3.id)).isNotNull
val senderDistributionRecords = getSenderRecoveryData(stx3.id, aliceNode.database).apply {
assertEquals(2, this.size)
assertEquals(this[0].timestamp, this[1].timestamp)
}
getReceiverRecoveryData(stx3.id, bobNode).apply {
assertThat(this).isNotNull
assertEquals(senderDistributionRecords[0].timestamp, this!!.timestamp)
}
getReceiverRecoveryData(stx3.id, charlieNode).apply {
assertThat(this).isNotNull
assertEquals(senderDistributionRecords[0].timestamp, this!!.timestamp)
}
}
private fun validateSenderAndReceiverTimestamps(sdrs: List<SenderDistributionRecord>, rdr: ReceiverDistributionRecord) {
sdrs.map {
assertEquals(it.timestamp, rdr.timestamp)
}
}
@Test(timeout=300_000)
fun `two phase finality flow payment transaction using confidential identities`() {
val bobNode = createBob(platformVersion = PlatformVersionSwitches.TWO_PHASE_FINALITY)
aliceNode.startFlow(CashIssueFlow(Amount(1000L, GBP), OpaqueBytes.of(1), notary)).resultFuture.getOrThrow().stx
val stx = aliceNode.startFlowAndRunNetwork(CashPaymentFlow(
amount = Amount(100L, GBP),
recipient = bobNode.info.singleIdentity(),
anonymous = true)).resultFuture.getOrThrow().stx
assertThat(aliceNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
assertThat(bobNode.services.validatedTransactions.getTransaction(stx.id)).isNotNull
val sdr = getSenderRecoveryData(stx.id, aliceNode.database).apply {
assertEquals(1, this.size)
assertEquals(StatesToRecord.ONLY_RELEVANT, this[0].senderStatesToRecord)
assertEquals(SecureHash.sha256(BOB_NAME.toString()), this[0].peerPartyId)
}
val rdr = getReceiverRecoveryData(stx.id, bobNode).apply {
assertNotNull(this)
val hashedDL = HashedDistributionList.decrypt(this!!.encryptedDistributionList.bytes, aliceNode.internals.encryptionService)
assertEquals(StatesToRecord.ONLY_RELEVANT, hashedDL.senderStatesToRecord)
assertEquals(SecureHash.sha256(aliceNode.info.singleIdentity().name.toString()), this.peerPartyId)
assertEquals(mapOf<SecureHash, StatesToRecord>(SecureHash.sha256(BOB_NAME.toString()) to StatesToRecord.ONLY_RELEVANT), hashedDL.peerHashToStatesToRecord)
}
validateSenderAndReceiverTimestamps(sdr, rdr!!)
}
private fun getSenderRecoveryData(id: SecureHash, database: CordaPersistence): List<SenderDistributionRecord> {
val fromDb = database.transaction {
session.createQuery(
"from ${DBSenderDistributionRecord::class.java.name} where transaction_id = :transactionId",
DBSenderDistributionRecord::class.java
).setParameter("transactionId", id.toString()).resultList
}
return fromDb.map { it.toSenderDistributionRecord() }
}
private fun getReceiverRecoveryData(txId: SecureHash, receiver: TestStartedNode): ReceiverDistributionRecord? {
return receiver.database.transaction {
session.createQuery(
"from ${DBReceiverDistributionRecord::class.java.name} where transaction_id = :transactionId",
DBReceiverDistributionRecord::class.java
).setParameter("transactionId", txId.toString()).resultList
}.singleOrNull()?.toReceiverDistributionRecord()
}
@StartableByRPC
class IssueFlow(val notary: Party) : FlowLogic<StateAndRef<DummyContract.SingleOwnerState>>() {
@Suspendable
override fun call(): StateAndRef<DummyContract.SingleOwnerState> {
val partyAndReference = PartyAndReference(ourIdentity, OpaqueBytes.of(1))
val txBuilder = DummyContract.generateInitial(Random().nextInt(), notary, partyAndReference)
val signedTransaction = serviceHub.signInitialTransaction(txBuilder, ourIdentity.owningKey)
val notarised = subFlow(FinalityFlow(signedTransaction, emptySet<FlowSession>()))
return notarised.coreTransaction.outRef(0)
}
}
@StartableByRPC
@InitiatingFlow
class SpendFlow(private val stateAndRef: StateAndRef<DummyContract.SingleOwnerState>, private val newOwner: Party,
private val handlePropagatedNotaryError: Boolean = false) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
val txBuilder = DummyContract.move(stateAndRef, newOwner)
val signedTransaction = serviceHub.signInitialTransaction(txBuilder, ourIdentity.owningKey)
val sessionWithCounterParty = initiateFlow(newOwner)
sessionWithCounterParty.send(handlePropagatedNotaryError)
return subFlow(FinalityFlow(signedTransaction, setOf(sessionWithCounterParty)))
}
}
@Suppress("unused")
@InitiatedBy(SpendFlow::class)
class AcceptSpendFlow(private val otherSide: FlowSession) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
val handleNotaryError = otherSide.receive<Boolean>().unwrap { it }
subFlow(ReceiveFinalityFlow(otherSide, handlePropagatedNotaryError = handleNotaryError))
}
}
/**
* This flow allows an Initiator to race ahead of a Receiver when using Two Phase Finality.
* The initiator transaction will be finalised, so output states can be used in a follow-up transaction.
* The receiver transaction will not be finalised, causing ledger inconsistency.
*/
@StartableByRPC
@InitiatingFlow
class SpeedySpendFlow(private val stateAndRef: StateAndRef<DummyContract.SingleOwnerState>, private val newOwner: Party) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
val newState = StateAndContract(DummyContract.SingleOwnerState(99999, ourIdentity), DummyContract.PROGRAM_ID)
val txBuilder = DummyContract.move(stateAndRef, newOwner).withItems(newState)
val signedTransaction = serviceHub.signInitialTransaction(txBuilder, ourIdentity.owningKey)
val sessionWithCounterParty = initiateFlow(newOwner)
try {
subFlow(FinalityFlow(signedTransaction, setOf(sessionWithCounterParty)))
}
catch (e: FinalisationFailedException) {
// expected (transaction has been notarised by Initiator)
return e.notarisedTxn
}
return signedTransaction
}
}
@Suppress("unused")
@InitiatedBy(SpeedySpendFlow::class)
class AcceptSpeedySpendFlow(private val otherSideSession: FlowSession) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
// Mimic ReceiveFinalityFlow but fail to finalise
try {
val stx = subFlow(ReceiveTransactionFlow(otherSideSession, false, StatesToRecord.ONLY_RELEVANT, true))
require(NotarySigCheck.needsNotarySignature(stx))
logger.info("Peer recording transaction without notary signature.")
(serviceHub as ServiceHubCoreInternal).recordUnnotarisedTransaction(stx)
otherSideSession.send(FetchDataFlow.Request.End) // Finish fetching data (overrideAutoAck)
logger.info("Peer recorded transaction without notary signature.")
val notarySignatures = otherSideSession.receive<List<TransactionSignature>>()
.unwrap { it }
logger.info("Peer received notarised signature.")
(serviceHub as ServiceHubCoreInternal).finalizeTransactionWithExtraSignatures(stx + notarySignatures, notarySignatures, StatesToRecord.ONLY_RELEVANT)
throw FinalisationFailedException(stx + notarySignatures)
}
catch (e: SQLException) {
logger.error("Peer failure upon recording or finalising transaction: $e")
otherSideSession.send(FetchDataFlow.Request.End) // Finish fetching data (overrideAutoAck)
throw UnexpectedFlowEndException("Peer failure upon recording or finalising transaction.", e.cause)
}
catch (uae: TransactionVerificationException.UntrustedAttachmentsException) {
logger.error("Peer failure upon receiving transaction: $uae")
otherSideSession.send(FetchDataFlow.Request.End) // Finish fetching data (overrideAutoAck)
throw uae
}
}
}
class FinaliseSpeedySpendFlow(val id: SecureHash, private val sigs: List<TransactionSignature>) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
// Mimic ReceiveFinalityFlow finalisation
val stx = serviceHub.validatedTransactions.getTransaction(id) ?: throw FlowException("Missing transaction: $id")
(serviceHub as ServiceHubCoreInternal).finalizeTransactionWithExtraSignatures(stx + sigs, sigs, StatesToRecord.ONLY_RELEVANT)
logger.info("Peer finalised transaction with notary signature.")
return stx + sigs
}
}
@InitiatingFlow
class MimicFinalityFailureFlow(private val stateAndRef: StateAndRef<DummyContract.SingleOwnerState>, private val newOwner: Party) : FlowLogic<SignedTransaction>() {
// Mimic FinalityFlow but trigger UnexpectedFlowEndException in ReceiveFinality whilst awaiting receipt of notary signature
@Suspendable
override fun call(): SignedTransaction {
val txBuilder = DummyContract.move(stateAndRef, newOwner)
val stxn = serviceHub.signInitialTransaction(txBuilder, ourIdentity.owningKey)
val sessionWithCounterParty = initiateFlow(newOwner)
subFlow(object : SendTransactionFlow(stxn, setOf(sessionWithCounterParty), emptySet(), StatesToRecord.ONLY_RELEVANT, true) {
override fun isFinality(): Boolean = true
})
throw UnexpectedFlowEndException("${stxn.id}")
}
}
@Suppress("unused")
@InitiatedBy(MimicFinalityFailureFlow::class)
class TriggerReceiveFinalityFlow(private val otherSide: FlowSession) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
subFlow(ReceiveFinalityFlow(otherSide))
}
}
class FinalisationFailedException(val notarisedTxn: SignedTransaction) : FlowException("Failed to finalise transaction with notary signature.")
private fun createBob(cordapps: List<TestCordappInternal> = emptyList(), platformVersion: Int = PLATFORM_VERSION): TestStartedNode {
return mockNet.createNode(InternalMockNodeParameters(legalName = BOB_NAME, additionalCordapps = cordapps,
version = MOCK_VERSION_INFO.copy(platformVersion = platformVersion)))
}
private fun createNode(legalName: CordaX500Name, cordapps: List<TestCordappInternal> = emptyList(), platformVersion: Int = PLATFORM_VERSION): TestStartedNode {
return mockNet.createNode(InternalMockNodeParameters(legalName = legalName, additionalCordapps = cordapps,
version = MOCK_VERSION_INFO.copy(platformVersion = platformVersion)))
} }
private fun TestStartedNode.issuesCashTo(recipient: TestStartedNode): SignedTransaction { private fun TestStartedNode.issuesCashTo(recipient: TestStartedNode): SignedTransaction {

View File

@ -15,7 +15,7 @@ class TestNoSecurityDataVendingFlow(otherSideSession: FlowSession) : DataVending
// Hack to not send the first message. // Hack to not send the first message.
otherSideSession.receive() otherSideSession.receive()
} else { } else {
super.sendPayloadAndReceiveDataRequest(this.otherSideSession, payload) super.sendPayloadAndReceiveDataRequest(this.otherSessions.first(), payload)
} }
} }
} }

View File

@ -4,7 +4,13 @@ import co.paralleluniverse.fibers.Suspendable
import com.natpryce.hamkrest.MatchResult import com.natpryce.hamkrest.MatchResult
import com.natpryce.hamkrest.Matcher import com.natpryce.hamkrest.Matcher
import com.natpryce.hamkrest.equalTo import com.natpryce.hamkrest.equalTo
import net.corda.core.flows.* import net.corda.core.flows.FinalityFlow
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowSession
import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.ReceiveFinalityFlow
import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.FlowStateMachineHandle import net.corda.core.internal.FlowStateMachineHandle
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
@ -58,4 +64,13 @@ interface WithFinality : WithMockNet {
subFlow(ReceiveFinalityFlow(otherSide)) subFlow(ReceiveFinalityFlow(otherSide))
} }
} }
@StartableByRPC
class OldFinalityInvoker(private val transaction: SignedTransaction) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
@Suppress("DEPRECATION")
return subFlow(FinalityFlow(transaction))
}
}
} }

View File

@ -99,12 +99,17 @@ class ResolveTransactionsFlowTest {
// DOCEND 1 // DOCEND 1
@Test(timeout=300_000) @Test(timeout=300_000)
fun `dependency with an error`() { fun `dependency with an error fails fast upon prior attempt to record transaction with missing signature`() {
val stx = makeTransactions(signFirstTX = false).second val exception = assertFailsWith(IllegalStateException::class) {
val p = TestFlow(setOf(stx.id), megaCorp) val stx = makeTransactions(signFirstTX = false).second
val future = miniCorpNode.startFlow(p) // fails fast in above operation
mockNet.runNetwork() // prior to platform version 13, same failure would occur upon transaction resolution
assertFailsWith(SignedTransaction.SignaturesMissingException::class) { future.getOrThrow() } val p = TestFlow(setOf(stx.id), megaCorp)
val future = miniCorpNode.startFlow(p)
mockNet.runNetwork()
future.getOrThrow()
}
assertTrue(exception.cause.toString().contains("SignaturesMissingException"))
} }
@Test(timeout=300_000) @Test(timeout=300_000)

View File

@ -30,6 +30,8 @@ import java.time.Duration
import java.time.Instant import java.time.Instant
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFails import kotlin.test.assertFails
import kotlin.test.assertNotEquals
import kotlin.test.assertNull
class NetworkParametersTest { class NetworkParametersTest {
private val mockNet = InternalMockNetwork( private val mockNet = InternalMockNetwork(
@ -93,6 +95,32 @@ class NetworkParametersTest {
assertEquals(twoDays, nm2.eventHorizon) assertEquals(twoDays, nm2.eventHorizon)
} }
@Test(timeout=300_000)
fun `that transactionRecoveryPeriod and confidentialIdentityPreGenerationPeriod aren't required`() {
// this is defensive tests in response to CORDA-2769
val aliceNotaryParty = TestIdentity(ALICE_NAME).party
val aliceNotaryInfo = NotaryInfo(aliceNotaryParty, false)
val nm1 = NetworkParameters(
minimumPlatformVersion = 1,
notaries = listOf(aliceNotaryInfo),
maxMessageSize = Int.MAX_VALUE,
maxTransactionSize = Int.MAX_VALUE,
modifiedTime = Instant.now(),
epoch = 1,
whitelistedContractImplementations = mapOf("MyClass" to listOf(AttachmentId.allOnesHash)),
eventHorizon = Duration.ofDays(1)
)
assertNull(nm1.recoveryMaximumBackupInterval)
assertNull(nm1.confidentialIdentityMinimumBackupInterval)
val nm2 = nm1.copy(recoveryMaximumBackupInterval = 10.days, confidentialIdentityMinimumBackupInterval = 10.days)
assertNotEquals(nm1.recoveryMaximumBackupInterval, nm2.recoveryMaximumBackupInterval)
assertNotEquals(nm1.confidentialIdentityMinimumBackupInterval, nm2.confidentialIdentityMinimumBackupInterval)
}
// Notaries tests // Notaries tests
@Test(timeout=300_000) @Test(timeout=300_000)
fun `choosing notary not specified in network parameters will fail`() { fun `choosing notary not specified in network parameters will fail`() {

View File

@ -80,7 +80,7 @@ class LedgerTransactionQueryTests {
.addOutputState(dummyState, DummyContract.PROGRAM_ID) .addOutputState(dummyState, DummyContract.PROGRAM_ID)
.addCommand(dummyCommand()) .addCommand(dummyCommand())
) )
services.recordTransactions(fakeIssueTx) services.recordTransactions(fakeIssueTx, disableSignatureVerification = true)
val dummyStateRef = StateRef(fakeIssueTx.id, 0) val dummyStateRef = StateRef(fakeIssueTx.id, 0)
return StateAndRef(TransactionState(dummyState, DummyContract.PROGRAM_ID, DUMMY_NOTARY, constraint = AlwaysAcceptAttachmentConstraint), dummyStateRef) return StateAndRef(TransactionState(dummyState, DummyContract.PROGRAM_ID, DUMMY_NOTARY, constraint = AlwaysAcceptAttachmentConstraint), dummyStateRef)
} }

View File

@ -9,7 +9,6 @@ apply plugin: 'com.jfrog.artifactory'
description 'Corda core' description 'Corda core'
// required by DJVM and Avian JVM (for running inside the SGX enclave) which only supports Java 8.
targetCompatibility = VERSION_1_8 targetCompatibility = VERSION_1_8
sourceSets { sourceSets {
@ -73,8 +72,8 @@ dependencies {
compile "net.i2p.crypto:eddsa:$eddsa_version" compile "net.i2p.crypto:eddsa:$eddsa_version"
// Bouncy castle support needed for X509 certificate manipulation // Bouncy castle support needed for X509 certificate manipulation
compile "org.bouncycastle:bcprov-jdk15on:${bouncycastle_version}" compile "org.bouncycastle:bcprov-jdk18on:${bouncycastle_version}"
compile "org.bouncycastle:bcpkix-jdk15on:${bouncycastle_version}" compile "org.bouncycastle:bcpkix-jdk18on:${bouncycastle_version}"
// JPA 2.2 annotations. // JPA 2.2 annotations.
compile "javax.persistence:javax.persistence-api:2.2" compile "javax.persistence:javax.persistence-api:2.2"

View File

@ -1,7 +1,5 @@
package net.corda.core.crypto; package net.corda.core.crypto;
import net.corda.core.KeepForDJVM;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays; import java.util.Arrays;
@ -29,7 +27,6 @@ import java.util.Arrays;
* NB: This class originally comes from the Apache licensed bitcoinj library. The original author of this code is the * NB: This class originally comes from the Apache licensed bitcoinj library. The original author of this code is the
* same as the original author of the R3 repository. * same as the original author of the R3 repository.
*/ */
@KeepForDJVM
public class Base58 { public class Base58 {
private static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray(); private static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
private static final char ENCODED_ZERO = ALPHABET[0]; private static final char ENCODED_ZERO = ALPHABET[0];

View File

@ -1,14 +1,11 @@
package net.corda.core.flows; package net.corda.core.flows;
import net.corda.core.KeepForDJVM;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** /**
* An exception that may be identified with an ID. If an exception originates in a counter-flow this ID will be * An exception that may be identified with an ID. If an exception originates in a counter-flow this ID will be
* propagated. This allows correlation of error conditions across different flows. * propagated. This allows correlation of error conditions across different flows.
*/ */
@KeepForDJVM
public interface IdentifiableException { public interface IdentifiableException {
/** /**
* @return the ID of the error, or null if the error doesn't have it set (yet). * @return the ID of the error, or null if the error doesn't have it set (yet).

View File

@ -6,6 +6,5 @@ import net.corda.core.serialization.CordaSerializable
* Allows an implementing [Throwable] to be propagated to clients. * Allows an implementing [Throwable] to be propagated to clients.
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM
@Deprecated("This is no longer used as the exception obfuscation feature is no longer available.") @Deprecated("This is no longer used as the exception obfuscation feature is no longer available.")
interface ClientRelevantError interface ClientRelevantError

View File

@ -4,7 +4,6 @@ import net.corda.core.serialization.CordaSerializable
import java.util.* import java.util.*
@CordaSerializable @CordaSerializable
@KeepForDJVM
interface CordaThrowable { interface CordaThrowable {
var originalExceptionClassName: String? var originalExceptionClassName: String?
val originalMessage: String? val originalMessage: String?
@ -13,7 +12,6 @@ interface CordaThrowable {
fun addSuppressed(suppressed: Array<Throwable>) fun addSuppressed(suppressed: Array<Throwable>)
} }
@KeepForDJVM
open class CordaException internal constructor(override var originalExceptionClassName: String? = null, open class CordaException internal constructor(override var originalExceptionClassName: String? = null,
private var _message: String? = null, private var _message: String? = null,
private var _cause: Throwable? = null) : Exception(null, null, true, true), CordaThrowable { private var _cause: Throwable? = null) : Exception(null, null, true, true), CordaThrowable {
@ -61,7 +59,6 @@ open class CordaException internal constructor(override var originalExceptionCla
} }
} }
@KeepForDJVM
open class CordaRuntimeException(override var originalExceptionClassName: String?, open class CordaRuntimeException(override var originalExceptionClassName: String?,
private var _message: String?, private var _message: String?,
private var _cause: Throwable?) : RuntimeException(null, null, true, true), CordaThrowable { private var _cause: Throwable?) : RuntimeException(null, null, true, true), CordaThrowable {

View File

@ -6,7 +6,6 @@ import net.corda.core.crypto.internal.AliasPrivateKey
* OIDs used for the Corda platform. All entries MUST be defined in this file only and they MUST NOT be removed. * OIDs used for the Corda platform. All entries MUST be defined in this file only and they MUST NOT be removed.
* If an OID is incorrectly assigned, it should be marked deprecated and NEVER be reused again. * If an OID is incorrectly assigned, it should be marked deprecated and NEVER be reused again.
*/ */
@KeepForDJVM
object CordaOID { object CordaOID {
/** Assigned to R3, see http://www.oid-info.com/cgi-bin/display?oid=1.3.6.1.4.1.50530&action=display */ /** Assigned to R3, see http://www.oid-info.com/cgi-bin/display?oid=1.3.6.1.4.1.50530&action=display */
const val R3_ROOT = "1.3.6.1.4.1.50530" const val R3_ROOT = "1.3.6.1.4.1.50530"

View File

@ -1,24 +0,0 @@
package net.corda.core
import kotlin.annotation.AnnotationRetention.BINARY
import kotlin.annotation.AnnotationTarget.*
/**
* Declare the annotated element to unsuitable for the deterministic version of Corda.
*/
// DOCSTART 01
@Target(
FILE,
CLASS,
CONSTRUCTOR,
FUNCTION,
PROPERTY_GETTER,
PROPERTY_SETTER,
PROPERTY,
FIELD,
TYPEALIAS
)
@Retention(BINARY)
@CordaInternal
annotation class DeleteForDJVM
// DOCEND 01

View File

@ -1,18 +0,0 @@
package net.corda.core
import kotlin.annotation.AnnotationRetention.BINARY
import kotlin.annotation.AnnotationTarget.CLASS
import kotlin.annotation.AnnotationTarget.FILE
/**
* This annotates a class or file that we want to include into the deterministic version of Corda Core.
* We don't expect everything within that class/file to be deterministic; those non-deterministic
* elements need to be annotated with either [DeleteForDJVM] or [StubOutForDJVM] so that they
* can be deleted.
*/
// DOCSTART 01
@Target(FILE, CLASS)
@Retention(BINARY)
@CordaInternal
annotation class KeepForDJVM
// DOCEND 01

View File

@ -1,22 +0,0 @@
package net.corda.core
import kotlin.annotation.AnnotationRetention.BINARY
import kotlin.annotation.AnnotationTarget.*
/**
* We expect that almost every non-deterministic element can have its bytecode
* deleted entirely from the deterministic version of Corda. This annotation is
* for those (hopefully!) few occasions where the non-deterministic function
* cannot be deleted. In these cases, the function will be stubbed out instead.
*/
// DOCSTART 01
@Target(
CONSTRUCTOR,
FUNCTION,
PROPERTY_GETTER,
PROPERTY_SETTER
)
@Retention(BINARY)
@CordaInternal
annotation class StubOutForDJVM
// DOCEND 01

View File

@ -1,7 +1,5 @@
package net.corda.core.context package net.corda.core.context
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.contracts.ScheduledStateRef import net.corda.core.contracts.ScheduledStateRef
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.telemetry.SerializedTelemetry import net.corda.core.internal.telemetry.SerializedTelemetry
@ -52,7 +50,6 @@ data class InvocationContext(
/** /**
* Creates an [InvocationContext] with a [Trace] that defaults to a [java.util.UUID] as value and [java.time.Instant.now] timestamp. * Creates an [InvocationContext] with a [Trace] that defaults to a [java.util.UUID] as value and [java.time.Instant.now] timestamp.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
@JvmOverloads @JvmOverloads
@Suppress("LongParameterList") @Suppress("LongParameterList")
@ -70,7 +67,6 @@ data class InvocationContext(
/** /**
* Creates an [InvocationContext] with [InvocationOrigin.RPC] origin. * Creates an [InvocationContext] with [InvocationOrigin.RPC] origin.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
@JvmOverloads @JvmOverloads
@Suppress("LongParameterList") @Suppress("LongParameterList")
@ -86,28 +82,24 @@ data class InvocationContext(
/** /**
* Creates an [InvocationContext] with [InvocationOrigin.Peer] origin. * Creates an [InvocationContext] with [InvocationOrigin.Peer] origin.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun peer(party: CordaX500Name, trace: Trace = Trace.newInstance(), externalTrace: Trace? = null, impersonatedActor: Actor? = null): InvocationContext = newInstance(InvocationOrigin.Peer(party), trace, null, externalTrace, impersonatedActor) fun peer(party: CordaX500Name, trace: Trace = Trace.newInstance(), externalTrace: Trace? = null, impersonatedActor: Actor? = null): InvocationContext = newInstance(InvocationOrigin.Peer(party), trace, null, externalTrace, impersonatedActor)
/** /**
* Creates an [InvocationContext] with [InvocationOrigin.Service] origin. * Creates an [InvocationContext] with [InvocationOrigin.Service] origin.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun service(serviceClassName: String, owningLegalIdentity: CordaX500Name, trace: Trace = Trace.newInstance(), externalTrace: Trace? = null): InvocationContext = newInstance(InvocationOrigin.Service(serviceClassName, owningLegalIdentity), trace, null, externalTrace) fun service(serviceClassName: String, owningLegalIdentity: CordaX500Name, trace: Trace = Trace.newInstance(), externalTrace: Trace? = null): InvocationContext = newInstance(InvocationOrigin.Service(serviceClassName, owningLegalIdentity), trace, null, externalTrace)
/** /**
* Creates an [InvocationContext] with [InvocationOrigin.Scheduled] origin. * Creates an [InvocationContext] with [InvocationOrigin.Scheduled] origin.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun scheduled(scheduledState: ScheduledStateRef, trace: Trace = Trace.newInstance(), externalTrace: Trace? = null): InvocationContext = newInstance(InvocationOrigin.Scheduled(scheduledState), trace, null, externalTrace) fun scheduled(scheduledState: ScheduledStateRef, trace: Trace = Trace.newInstance(), externalTrace: Trace? = null): InvocationContext = newInstance(InvocationOrigin.Scheduled(scheduledState), trace, null, externalTrace)
/** /**
* Creates an [InvocationContext] with [InvocationOrigin.Shell] origin. * Creates an [InvocationContext] with [InvocationOrigin.Shell] origin.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun shell(trace: Trace = Trace.newInstance(), externalTrace: Trace? = null): InvocationContext = InvocationContext(InvocationOrigin.Shell, trace, null, externalTrace) fun shell(trace: Trace = Trace.newInstance(), externalTrace: Trace? = null): InvocationContext = InvocationContext(InvocationOrigin.Shell, trace, null, externalTrace)
} }
@ -161,7 +153,6 @@ data class InvocationContext(
/** /**
* Models an initiator in Corda, can be a user, a service, etc. * Models an initiator in Corda, can be a user, a service, etc.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
data class Actor(val id: Id, val serviceId: AuthServiceId, val owningLegalIdentity: CordaX500Name) { data class Actor(val id: Id, val serviceId: AuthServiceId, val owningLegalIdentity: CordaX500Name) {
@ -173,7 +164,6 @@ data class Actor(val id: Id, val serviceId: AuthServiceId, val owningLegalIdenti
/** /**
* Actor id. * Actor id.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
data class Id(val value: String) data class Id(val value: String)
} }
@ -181,7 +171,6 @@ data class Actor(val id: Id, val serviceId: AuthServiceId, val owningLegalIdenti
/** /**
* Represents the source of an action such as a flow start, an RPC, a shell command etc. * Represents the source of an action such as a flow start, an RPC, a shell command etc.
*/ */
@DeleteForDJVM
@CordaSerializable @CordaSerializable
sealed class InvocationOrigin { sealed class InvocationOrigin {
/** /**
@ -230,6 +219,5 @@ sealed class InvocationOrigin {
/** /**
* Authentication / Authorisation Service ID. * Authentication / Authorisation Service ID.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
data class AuthServiceId(val value: String) data class AuthServiceId(val value: String)

View File

@ -1,6 +1,5 @@
package net.corda.core.context package net.corda.core.context
import net.corda.core.DeleteForDJVM
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.Id import net.corda.core.utilities.Id
import net.corda.core.utilities.UuidGenerator import net.corda.core.utilities.UuidGenerator
@ -17,7 +16,6 @@ data class Trace(val invocationId: InvocationId, val sessionId: SessionId) {
/** /**
* Creates a trace using a [InvocationId.newInstance] with default arguments and a [SessionId] matching the value and timestamp from the invocation id.. * Creates a trace using a [InvocationId.newInstance] with default arguments and a [SessionId] matching the value and timestamp from the invocation id..
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun newInstance(invocationId: InvocationId = InvocationId.newInstance(), sessionId: SessionId = SessionId(invocationId.value, invocationId.timestamp)) = Trace(invocationId, sessionId) fun newInstance(invocationId: InvocationId = InvocationId.newInstance(), sessionId: SessionId = SessionId(invocationId.value, invocationId.timestamp)) = Trace(invocationId, sessionId)
} }
@ -34,7 +32,6 @@ data class Trace(val invocationId: InvocationId, val sessionId: SessionId) {
/** /**
* Creates an invocation id using a [java.util.UUID] as value and [Instant.now] as timestamp. * Creates an invocation id using a [java.util.UUID] as value and [Instant.now] as timestamp.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun newInstance(value: String = UuidGenerator.next().toString(), timestamp: Instant = Instant.now()) = InvocationId(value, timestamp) fun newInstance(value: String = UuidGenerator.next().toString(), timestamp: Instant = Instant.now()) = InvocationId(value, timestamp)
} }
@ -52,9 +49,8 @@ data class Trace(val invocationId: InvocationId, val sessionId: SessionId) {
/** /**
* Creates a session id using a [java.util.UUID] as value and [Instant.now] as timestamp. * Creates a session id using a [java.util.UUID] as value and [Instant.now] as timestamp.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun newInstance(value: String = UuidGenerator.next().toString(), timestamp: Instant = Instant.now()) = SessionId(value, timestamp) fun newInstance(value: String = UuidGenerator.next().toString(), timestamp: Instant = Instant.now()) = SessionId(value, timestamp)
} }
} }
} }

View File

@ -1,6 +1,5 @@
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.KeepForDJVM
import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.CompositeKey
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
@ -37,7 +36,6 @@ interface TokenizableAssetInfo {
* @property token the type of token this is an amount of. This is usually a singleton. * @property token the type of token this is an amount of. This is usually a singleton.
* @param T the type of the token, for example [Currency]. T should implement [TokenizableAssetInfo] if automatic conversion to/from a display format is required. * @param T the type of the token, for example [Currency]. T should implement [TokenizableAssetInfo] if automatic conversion to/from a display format is required.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
data class Amount<T : Any>(val quantity: Long, val displayTokenSize: BigDecimal, val token: T) : Comparable<Amount<T>> { data class Amount<T : Any>(val quantity: Long, val displayTokenSize: BigDecimal, val token: T) : Comparable<Amount<T>> {
// TODO Proper lookup of currencies in a locale and context sensitive fashion is not supported and is left to the application. // TODO Proper lookup of currencies in a locale and context sensitive fashion is not supported and is left to the application.

View File

@ -1,7 +1,6 @@
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.DoNotImplement import net.corda.core.DoNotImplement
import net.corda.core.KeepForDJVM
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.extractFile import net.corda.core.internal.extractFile
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
@ -31,7 +30,6 @@ import java.util.jar.JarInputStream
* Finally, using ZIPs ensures files have a timestamp associated with them, and enables informational attachments * Finally, using ZIPs ensures files have a timestamp associated with them, and enables informational attachments
* to be password protected (although in current releases password protected ZIPs are likely to fail to work). * to be password protected (although in current releases password protected ZIPs are likely to fail to work).
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
@DoNotImplement @DoNotImplement
interface Attachment : NamedByHash { interface Attachment : NamedByHash {

View File

@ -2,7 +2,6 @@ package net.corda.core.contracts
import net.corda.core.CordaInternal import net.corda.core.CordaInternal
import net.corda.core.DoNotImplement import net.corda.core.DoNotImplement
import net.corda.core.KeepForDJVM
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint.isSatisfiedBy import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint.isSatisfiedBy
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.isFulfilledBy import net.corda.core.crypto.isFulfilledBy
@ -38,7 +37,6 @@ interface AttachmentConstraint {
} }
/** An [AttachmentConstraint] where [isSatisfiedBy] always returns true. */ /** An [AttachmentConstraint] where [isSatisfiedBy] always returns true. */
@KeepForDJVM
object AlwaysAcceptAttachmentConstraint : AttachmentConstraint { object AlwaysAcceptAttachmentConstraint : AttachmentConstraint {
override fun isSatisfiedBy(attachment: Attachment) = true override fun isSatisfiedBy(attachment: Attachment) = true
} }
@ -48,7 +46,6 @@ object AlwaysAcceptAttachmentConstraint : AttachmentConstraint {
* The state protected by this constraint can only be used in a transaction created with that version of the jar. * The state protected by this constraint can only be used in a transaction created with that version of the jar.
* And a receiving node will only accept it if a cordapp with that hash has (is) been deployed on the node. * And a receiving node will only accept it if a cordapp with that hash has (is) been deployed on the node.
*/ */
@KeepForDJVM
data class HashAttachmentConstraint(val attachmentId: SecureHash) : AttachmentConstraint { data class HashAttachmentConstraint(val attachmentId: SecureHash) : AttachmentConstraint {
companion object { companion object {
val disableHashConstraints = System.getProperty("net.corda.node.disableHashConstraints")?.toBoolean() ?: false val disableHashConstraints = System.getProperty("net.corda.node.disableHashConstraints")?.toBoolean() ?: false
@ -69,7 +66,6 @@ data class HashAttachmentConstraint(val attachmentId: SecureHash) : AttachmentCo
* See: [net.corda.core.node.NetworkParameters.whitelistedContractImplementations] * See: [net.corda.core.node.NetworkParameters.whitelistedContractImplementations]
* It allows for centralized control over the cordapps that can be used. * It allows for centralized control over the cordapps that can be used.
*/ */
@KeepForDJVM
object WhitelistedByZoneAttachmentConstraint : AttachmentConstraint { object WhitelistedByZoneAttachmentConstraint : AttachmentConstraint {
override fun isSatisfiedBy(attachment: Attachment): Boolean { override fun isSatisfiedBy(attachment: Attachment): Boolean {
return if (attachment is AttachmentWithContext) { return if (attachment is AttachmentWithContext) {
@ -83,7 +79,6 @@ object WhitelistedByZoneAttachmentConstraint : AttachmentConstraint {
} }
} }
@KeepForDJVM
@Deprecated( @Deprecated(
"The name is no longer valid as multiple constraints were added.", "The name is no longer valid as multiple constraints were added.",
replaceWith = ReplaceWith("AutomaticPlaceholderConstraint"), replaceWith = ReplaceWith("AutomaticPlaceholderConstraint"),
@ -102,7 +97,6 @@ object AutomaticHashConstraint : AttachmentConstraint {
* The resolution occurs in [TransactionBuilder.toWireTransaction] and is based on the input states and the attachments. * The resolution occurs in [TransactionBuilder.toWireTransaction] and is based on the input states and the attachments.
* If the [Contract] was not annotated with [NoConstraintPropagation], then the platform will ensure the correct constraint propagation. * If the [Contract] was not annotated with [NoConstraintPropagation], then the platform will ensure the correct constraint propagation.
*/ */
@KeepForDJVM
object AutomaticPlaceholderConstraint : AttachmentConstraint { object AutomaticPlaceholderConstraint : AttachmentConstraint {
override fun isSatisfiedBy(attachment: Attachment): Boolean { override fun isSatisfiedBy(attachment: Attachment): Boolean {
throw UnsupportedOperationException("Contracts cannot be satisfied by an AutomaticPlaceholderConstraint placeholder.") throw UnsupportedOperationException("Contracts cannot be satisfied by an AutomaticPlaceholderConstraint placeholder.")
@ -115,7 +109,6 @@ object AutomaticPlaceholderConstraint : AttachmentConstraint {
* *
* @property key A [PublicKey] that must be fulfilled by the owning keys of the attachment's signing parties. * @property key A [PublicKey] that must be fulfilled by the owning keys of the attachment's signing parties.
*/ */
@KeepForDJVM
data class SignatureAttachmentConstraint(val key: PublicKey) : AttachmentConstraint { data class SignatureAttachmentConstraint(val key: PublicKey) : AttachmentConstraint {
override fun isSatisfiedBy(attachment: Attachment): Boolean { override fun isSatisfiedBy(attachment: Attachment): Boolean {
log.debug("Checking signature constraints: verifying $key in contract attachment signer keys: ${attachment.signerKeys}") log.debug("Checking signature constraints: verifying $key in contract attachment signer keys: ${attachment.signerKeys}")

View File

@ -1,7 +1,6 @@
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.CordaInternal import net.corda.core.CordaInternal
import net.corda.core.KeepForDJVM
import net.corda.core.internal.cordapp.CordappImpl.Companion.DEFAULT_CORDAPP_VERSION import net.corda.core.internal.cordapp.CordappImpl.Companion.DEFAULT_CORDAPP_VERSION
import java.security.PublicKey import java.security.PublicKey
@ -12,7 +11,6 @@ import java.security.PublicKey
* @property contract The contract name contained within the JAR. A Contract attachment has to contain at least 1 contract. * @property contract The contract name contained within the JAR. A Contract attachment has to contain at least 1 contract.
* @property additionalContracts Additional contract names contained within the JAR. * @property additionalContracts Additional contract names contained within the JAR.
*/ */
@KeepForDJVM
class ContractAttachment private constructor( class ContractAttachment private constructor(
val attachment: Attachment, val attachment: Attachment,
val contract: ContractClassName, val contract: ContractClassName,

View File

@ -1,6 +1,5 @@
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.KeepForDJVM
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
@ -12,7 +11,6 @@ import net.corda.core.serialization.CordaSerializable
* notary is responsible for ensuring there is no "double spending" by only signing a transaction if the input states * notary is responsible for ensuring there is no "double spending" by only signing a transaction if the input states
* are all free. * are all free.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
interface ContractState { interface ContractState {
/** /**

View File

@ -1,8 +1,6 @@
@file:JvmName("ContractsDSL") @file:JvmName("ContractsDSL")
@file:KeepForDJVM
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.KeepForDJVM
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.uncheckedCast import net.corda.core.internal.uncheckedCast
@ -18,7 +16,6 @@ import java.util.*
//// Requirements ///////////////////////////////////////////////////////////////////////////////////////////////////// //// Requirements /////////////////////////////////////////////////////////////////////////////////////////////////////
@KeepForDJVM
object Requirements { object Requirements {
/** Throws [IllegalArgumentException] if the given expression evaluates to false. */ /** Throws [IllegalArgumentException] if the given expression evaluates to false. */
@Suppress("NOTHING_TO_INLINE") // Inlining this takes it out of our committed ABI. @Suppress("NOTHING_TO_INLINE") // Inlining this takes it out of our committed ABI.

View File

@ -1,6 +1,5 @@
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.KeepForDJVM
import net.corda.core.flows.FlowException import net.corda.core.flows.FlowException
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.serialization.SerializableCalculatedProperty import net.corda.core.serialization.SerializableCalculatedProperty
@ -27,7 +26,6 @@ class InsufficientBalanceException(val amountMissing: Amount<*>) : FlowException
* @param T a type that represents the asset in question. This should describe the basic type of the asset * @param T a type that represents the asset in question. This should describe the basic type of the asset
* (GBP, USD, oil, shares in company <X>, etc.) and any additional metadata (issuer, grade, class, etc.). * (GBP, USD, oil, shares in company <X>, etc.) and any additional metadata (issuer, grade, class, etc.).
*/ */
@KeepForDJVM
interface FungibleAsset<T : Any> : FungibleState<Issued<T>>, OwnableState { interface FungibleAsset<T : Any> : FungibleState<Issued<T>>, OwnableState {
/** /**
* Amount represents a positive quantity of some issued product which can be cash, tokens, assets, or generally * Amount represents a positive quantity of some issued product which can be cash, tokens, assets, or generally

View File

@ -1,7 +1,5 @@
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.KeepForDJVM
/** /**
* Interface to represent things which are fungible, this means that there is an expectation that these things can * Interface to represent things which are fungible, this means that there is an expectation that these things can
* be split and merged. That's the only assumption made by this interface. * be split and merged. That's the only assumption made by this interface.
@ -25,7 +23,6 @@ import net.corda.core.KeepForDJVM
* [TokenizableAssetInfo]. * [TokenizableAssetInfo].
*/ */
// DOCSTART 1 // DOCSTART 1
@KeepForDJVM
interface FungibleState<T : Any> : ContractState { interface FungibleState<T : Any> : ContractState {
/** /**
* Amount represents a positive quantity of some token which can be cash, tokens, stock, agreements, or generally * Amount represents a positive quantity of some token which can be cash, tokens, stock, agreements, or generally

View File

@ -1,8 +1,6 @@
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.DeleteForDJVM
import net.corda.core.DoNotImplement import net.corda.core.DoNotImplement
import net.corda.core.KeepForDJVM
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.node.services.queryBy import net.corda.core.node.services.queryBy
@ -18,7 +16,6 @@ import net.corda.core.transactions.LedgerTransaction
* [StaticPointer]s are for use with any type of [ContractState]. * [StaticPointer]s are for use with any type of [ContractState].
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM
@DoNotImplement @DoNotImplement
sealed class StatePointer<T : ContractState> { sealed class StatePointer<T : ContractState> {
@ -70,7 +67,6 @@ sealed class StatePointer<T : ContractState> {
* *
* @param services a [ServiceHub] implementation is required to resolve the pointer. * @param services a [ServiceHub] implementation is required to resolve the pointer.
*/ */
@DeleteForDJVM
abstract fun resolve(services: ServiceHub): StateAndRef<T> abstract fun resolve(services: ServiceHub): StateAndRef<T>
/** /**
@ -89,7 +85,6 @@ sealed class StatePointer<T : ContractState> {
* - The [ContractState] may not be known by the node performing the look-up in which case the [resolve] method will * - The [ContractState] may not be known by the node performing the look-up in which case the [resolve] method will
* throw a [TransactionResolutionException] * throw a [TransactionResolutionException]
*/ */
@KeepForDJVM
class StaticPointer<T : ContractState>( class StaticPointer<T : ContractState>(
override val pointer: StateRef, override val pointer: StateRef,
override val type: Class<T>, override val type: Class<T>,
@ -110,7 +105,6 @@ class StaticPointer<T : ContractState>(
*/ */
@Throws(TransactionResolutionException::class) @Throws(TransactionResolutionException::class)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@DeleteForDJVM
override fun resolve(services: ServiceHub): StateAndRef<T> { override fun resolve(services: ServiceHub): StateAndRef<T> {
val transactionState = services.loadState(pointer) as TransactionState<T> val transactionState = services.loadState(pointer) as TransactionState<T>
val castState: T = type.cast(transactionState.data) val castState: T = type.cast(transactionState.data)
@ -148,7 +142,6 @@ class StaticPointer<T : ContractState>(
* then the transaction with such a reference state cannot be committed to the ledger until the most up-to-date version * then the transaction with such a reference state cannot be committed to the ledger until the most up-to-date version
* of the [LinearState] is available. See reference states documentation on docs.corda.net for more info. * of the [LinearState] is available. See reference states documentation on docs.corda.net for more info.
*/ */
@KeepForDJVM
class LinearPointer<T : LinearState>( class LinearPointer<T : LinearState>(
override val pointer: UniqueIdentifier, override val pointer: UniqueIdentifier,
override val type: Class<T>, override val type: Class<T>,
@ -171,7 +164,6 @@ class LinearPointer<T : LinearState>(
* @param services a [ServiceHub] implementation is required to perform a vault query. * @param services a [ServiceHub] implementation is required to perform a vault query.
*/ */
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@DeleteForDJVM
override fun resolve(services: ServiceHub): StateAndRef<T> { override fun resolve(services: ServiceHub): StateAndRef<T> {
// Return the latest version of the linear state. // Return the latest version of the linear state.
// This query will only ever return one or zero states. // This query will only ever return one or zero states.

View File

@ -1,9 +1,6 @@
@file:JvmName("Structures") @file:JvmName("Structures")
@file:KeepForDJVM
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.secureRandomBytes import net.corda.core.crypto.secureRandomBytes
import net.corda.core.crypto.toStringShort import net.corda.core.crypto.toStringShort
@ -45,7 +42,6 @@ interface NamedByHash {
* of product may differentiate different kinds of asset within the same logical class e.g the currency, or * of product may differentiate different kinds of asset within the same logical class e.g the currency, or
* it may just be a type marker for a single custom asset. * it may just be a type marker for a single custom asset.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
data class Issued<out P : Any>(val issuer: PartyAndReference, val product: P) { data class Issued<out P : Any>(val issuer: PartyAndReference, val product: P) {
init { init {
@ -72,13 +68,11 @@ fun <T : Any> Amount<Issued<T>>.withoutIssuer(): Amount<T> = Amount(quantity, di
/** /**
* Return structure for [OwnableState.withNewOwner] * Return structure for [OwnableState.withNewOwner]
*/ */
@KeepForDJVM
data class CommandAndState(val command: CommandData, val ownableState: OwnableState) data class CommandAndState(val command: CommandData, val ownableState: OwnableState)
/** /**
* A contract state that can have a single owner. * A contract state that can have a single owner.
*/ */
@KeepForDJVM
interface OwnableState : ContractState { interface OwnableState : ContractState {
/** There must be a MoveCommand signed by this key to claim the amount. */ /** There must be a MoveCommand signed by this key to claim the amount. */
val owner: AbstractParty val owner: AbstractParty
@ -89,7 +83,6 @@ interface OwnableState : ContractState {
// DOCEND 3 // DOCEND 3
/** Something which is scheduled to happen at a point in time. */ /** Something which is scheduled to happen at a point in time. */
@KeepForDJVM
interface Scheduled { interface Scheduled {
val scheduledAt: Instant val scheduledAt: Instant
} }
@ -102,7 +95,6 @@ interface Scheduled {
* lifecycle processing needs to take place. e.g. a fixing or a late payment etc. * lifecycle processing needs to take place. e.g. a fixing or a late payment etc.
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM
data class ScheduledStateRef(val ref: StateRef, override val scheduledAt: Instant) : Scheduled data class ScheduledStateRef(val ref: StateRef, override val scheduledAt: Instant) : Scheduled
/** /**
@ -117,7 +109,6 @@ data class ScheduledStateRef(val ref: StateRef, override val scheduledAt: Instan
* for a particular [ContractState] have been processed/fired etc. If the activity is not "on ledger" then the * for a particular [ContractState] have been processed/fired etc. If the activity is not "on ledger" then the
* scheduled activity shouldn't be either. * scheduled activity shouldn't be either.
*/ */
@KeepForDJVM
data class ScheduledActivity(val logicRef: FlowLogicRef, override val scheduledAt: Instant) : Scheduled data class ScheduledActivity(val logicRef: FlowLogicRef, override val scheduledAt: Instant) : Scheduled
// DOCSTART 2 // DOCSTART 2
@ -126,7 +117,6 @@ data class ScheduledActivity(val logicRef: FlowLogicRef, override val scheduledA
* *
* This simplifies the job of tracking the current version of certain types of state in e.g. a vault. * This simplifies the job of tracking the current version of certain types of state in e.g. a vault.
*/ */
@KeepForDJVM
interface LinearState : ContractState { interface LinearState : ContractState {
/** /**
* Unique id shared by all LinearState states throughout history within the vaults of all parties. * Unique id shared by all LinearState states throughout history within the vaults of all parties.
@ -136,7 +126,6 @@ interface LinearState : ContractState {
val linearId: UniqueIdentifier val linearId: UniqueIdentifier
} }
// DOCEND 2 // DOCEND 2
@KeepForDJVM
interface SchedulableState : ContractState { interface SchedulableState : ContractState {
/** /**
* Indicate whether there is some activity to be performed at some future point in time with respect to this * Indicate whether there is some activity to be performed at some future point in time with respect to this
@ -160,7 +149,6 @@ fun ContractState.hash(algorithm: String): SecureHash = SecureHash.hashAs(algori
* A stateref is a pointer (reference) to a state, this is an equivalent of an "outpoint" in Bitcoin. It records which * A stateref is a pointer (reference) to a state, this is an equivalent of an "outpoint" in Bitcoin. It records which
* transaction defined the state and where in that transaction it was. * transaction defined the state and where in that transaction it was.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
// DOCSTART 8 // DOCSTART 8
data class StateRef(val txhash: SecureHash, val index: Int) { data class StateRef(val txhash: SecureHash, val index: Int) {
@ -169,7 +157,6 @@ data class StateRef(val txhash: SecureHash, val index: Int) {
// DOCEND 8 // DOCEND 8
/** A StateAndRef is simply a (state, ref) pair. For instance, a vault (which holds available assets) contains these. */ /** A StateAndRef is simply a (state, ref) pair. For instance, a vault (which holds available assets) contains these. */
@KeepForDJVM
@CordaSerializable @CordaSerializable
// DOCSTART 7 // DOCSTART 7
data class StateAndRef<out T : ContractState>(val state: TransactionState<T>, val ref: StateRef) { data class StateAndRef<out T : ContractState>(val state: TransactionState<T>, val ref: StateRef) {
@ -179,7 +166,6 @@ data class StateAndRef<out T : ContractState>(val state: TransactionState<T>, va
// DOCEND 7 // DOCEND 7
/** A wrapper for a [StateAndRef] indicating that it should be added to a transaction as a reference input state. */ /** A wrapper for a [StateAndRef] indicating that it should be added to a transaction as a reference input state. */
@KeepForDJVM
data class ReferencedStateAndRef<out T : ContractState>(val stateAndRef: StateAndRef<T>) data class ReferencedStateAndRef<out T : ContractState>(val stateAndRef: StateAndRef<T>)
/** Filters a list of [StateAndRef] objects according to the type of the states */ /** Filters a list of [StateAndRef] objects according to the type of the states */
@ -191,7 +177,6 @@ inline fun <reified T : ContractState> Iterable<StateAndRef<ContractState>>.filt
* Reference to something being stored or issued by a party e.g. in a vault or (more likely) on their normal * Reference to something being stored or issued by a party e.g. in a vault or (more likely) on their normal
* ledger. The reference is intended to be encrypted so it's meaningless to anyone other than the party. * ledger. The reference is intended to be encrypted so it's meaningless to anyone other than the party.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
data class PartyAndReference(val party: AbstractParty, val reference: OpaqueBytes) { data class PartyAndReference(val party: AbstractParty, val reference: OpaqueBytes) {
override fun toString() = "$party$reference" override fun toString() = "$party$reference"
@ -202,14 +187,12 @@ data class PartyAndReference(val party: AbstractParty, val reference: OpaqueByte
interface CommandData interface CommandData
/** Commands that inherit from this are intended to have no data items: it's only their presence that matters. */ /** Commands that inherit from this are intended to have no data items: it's only their presence that matters. */
@KeepForDJVM
abstract class TypeOnlyCommandData : CommandData { abstract class TypeOnlyCommandData : CommandData {
override fun equals(other: Any?) = other?.javaClass == javaClass override fun equals(other: Any?) = other?.javaClass == javaClass
override fun hashCode() = javaClass.name.hashCode() override fun hashCode() = javaClass.name.hashCode()
} }
/** Command data/content plus pubkey pair: the signature is stored at the end of the serialized bytes */ /** Command data/content plus pubkey pair: the signature is stored at the end of the serialized bytes */
@KeepForDJVM
@CordaSerializable @CordaSerializable
data class Command<T : CommandData>(val value: T, val signers: List<PublicKey>) { data class Command<T : CommandData>(val value: T, val signers: List<PublicKey>) {
// TODO Introduce NonEmptyList? // TODO Introduce NonEmptyList?
@ -224,7 +207,6 @@ data class Command<T : CommandData>(val value: T, val signers: List<PublicKey>)
} }
/** A common move command for contract states which can change owner. */ /** A common move command for contract states which can change owner. */
@KeepForDJVM
interface MoveCommand : CommandData { interface MoveCommand : CommandData {
/** /**
* Contract code the moved state(s) are for the attention of, for example to indicate that the states are moved in * Contract code the moved state(s) are for the attention of, for example to indicate that the states are moved in
@ -236,7 +218,6 @@ interface MoveCommand : CommandData {
// DOCSTART 6 // DOCSTART 6
/** A [Command] where the signing parties have been looked up if they have a well known/recognised institutional key. */ /** A [Command] where the signing parties have been looked up if they have a well known/recognised institutional key. */
@KeepForDJVM
@CordaSerializable @CordaSerializable
data class CommandWithParties<out T : CommandData>( data class CommandWithParties<out T : CommandData>(
val signers: List<PublicKey>, val signers: List<PublicKey>,
@ -256,7 +237,6 @@ data class CommandWithParties<out T : CommandData>(
* *
* TODO: Contract serialization is likely to change, so the annotation is likely temporary. * TODO: Contract serialization is likely to change, so the annotation is likely temporary.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
interface Contract { interface Contract {
/** /**
@ -288,7 +268,6 @@ annotation class LegalProseReference(val uri: String)
* more than one state). * more than one state).
* @param NewState the upgraded contract state. * @param NewState the upgraded contract state.
*/ */
@KeepForDJVM
interface UpgradedContract<in OldState : ContractState, out NewState : ContractState> : Contract { interface UpgradedContract<in OldState : ContractState, out NewState : ContractState> : Contract {
/** /**
* Name of the contract this is an upgraded version of, used as part of verification of upgrade transactions. * Name of the contract this is an upgraded version of, used as part of verification of upgrade transactions.
@ -307,7 +286,6 @@ interface UpgradedContract<in OldState : ContractState, out NewState : ContractS
* This interface allows specifying a custom legacy contract constraint for upgraded contracts. The default for [UpgradedContract] * This interface allows specifying a custom legacy contract constraint for upgraded contracts. The default for [UpgradedContract]
* is [WhitelistedByZoneAttachmentConstraint]. * is [WhitelistedByZoneAttachmentConstraint].
*/ */
@KeepForDJVM
interface UpgradedContractWithLegacyConstraint<in OldState : ContractState, out NewState : ContractState> : UpgradedContract<OldState, NewState> { interface UpgradedContractWithLegacyConstraint<in OldState : ContractState, out NewState : ContractState> : UpgradedContract<OldState, NewState> {
/** /**
* A validator for the legacy (pre-upgrade) contract attachments on the transaction. * A validator for the legacy (pre-upgrade) contract attachments on the transaction.
@ -325,14 +303,11 @@ interface UpgradedContractWithLegacyConstraint<in OldState : ContractState, out
* but it is highlighted that one should always ensure it has sufficient entropy. * but it is highlighted that one should always ensure it has sufficient entropy.
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM
class PrivacySalt(bytes: ByteArray) : OpaqueBytes(bytes) { class PrivacySalt(bytes: ByteArray) : OpaqueBytes(bytes) {
/** Constructs a salt with a randomly-generated saltLength byte value. */ /** Constructs a salt with a randomly-generated saltLength byte value. */
@DeleteForDJVM
constructor(saltLength: Int) : this(secureRandomBytes(saltLength)) constructor(saltLength: Int) : this(secureRandomBytes(saltLength))
/** Constructs a salt with a randomly-generated 32 byte value. */ /** Constructs a salt with a randomly-generated 32 byte value. */
@DeleteForDJVM
constructor() : this(MINIMUM_SIZE) constructor() : this(MINIMUM_SIZE)
init { init {
@ -343,7 +318,6 @@ class PrivacySalt(bytes: ByteArray) : OpaqueBytes(bytes) {
companion object { companion object {
private const val MINIMUM_SIZE = 32 private const val MINIMUM_SIZE = 32
@DeleteForDJVM
@JvmStatic @JvmStatic
fun createFor(algorithm: String): PrivacySalt { fun createFor(algorithm: String): PrivacySalt {
return PrivacySalt(SecureHash.digestLengthFor(algorithm)) return PrivacySalt(SecureHash.digestLengthFor(algorithm))
@ -357,5 +331,4 @@ class PrivacySalt(bytes: ByteArray) : OpaqueBytes(bytes) {
* @property state A state * @property state A state
* @property contract The contract that should verify the state * @property contract The contract that should verify the state
*/ */
@KeepForDJVM
data class StateAndContract(val state: ContractState, val contract: ContractClassName) data class StateAndContract(val state: ContractState, val contract: ContractClassName)

View File

@ -1,6 +1,5 @@
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.KeepForDJVM
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.until import net.corda.core.internal.until
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
@ -79,7 +78,6 @@ abstract class TimeWindow {
/** Returns true iff the given [instant] is within the time interval of this [TimeWindow]. */ /** Returns true iff the given [instant] is within the time interval of this [TimeWindow]. */
abstract operator fun contains(instant: Instant): Boolean abstract operator fun contains(instant: Instant): Boolean
@KeepForDJVM
private data class From(override val fromTime: Instant) : TimeWindow() { private data class From(override val fromTime: Instant) : TimeWindow() {
override val untilTime: Instant? get() = null override val untilTime: Instant? get() = null
override val midpoint: Instant? get() = null override val midpoint: Instant? get() = null
@ -87,7 +85,6 @@ abstract class TimeWindow {
override fun toString(): String = "[$fromTime, ∞)" override fun toString(): String = "[$fromTime, ∞)"
} }
@KeepForDJVM
private data class Until(override val untilTime: Instant) : TimeWindow() { private data class Until(override val untilTime: Instant) : TimeWindow() {
override val fromTime: Instant? get() = null override val fromTime: Instant? get() = null
override val midpoint: Instant? get() = null override val midpoint: Instant? get() = null
@ -95,7 +92,6 @@ abstract class TimeWindow {
override fun toString(): String = "(∞, $untilTime)" override fun toString(): String = "(∞, $untilTime)"
} }
@KeepForDJVM
private data class Between(override val fromTime: Instant, override val untilTime: Instant) : TimeWindow() { private data class Between(override val fromTime: Instant, override val untilTime: Instant) : TimeWindow() {
init { init {
require(fromTime < untilTime) { "fromTime must be earlier than untilTime" } require(fromTime < untilTime) { "fromTime must be earlier than untilTime" }

View File

@ -1,7 +1,5 @@
@file:KeepForDJVM
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.KeepForDJVM
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.requiredContractClassName import net.corda.core.internal.requiredContractClassName
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable

View File

@ -1,8 +1,6 @@
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.CordaException import net.corda.core.CordaException
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowException import net.corda.core.flows.FlowException
import net.corda.core.identity.Party import net.corda.core.identity.Party
@ -18,7 +16,6 @@ import java.security.PublicKey
* *
* @property hash Merkle root of the transaction being resolved, see [net.corda.core.transactions.WireTransaction.id] * @property hash Merkle root of the transaction being resolved, see [net.corda.core.transactions.WireTransaction.id]
*/ */
@KeepForDJVM
open class TransactionResolutionException @JvmOverloads constructor(val hash: SecureHash, message: String = "Transaction resolution failure for $hash") : FlowException(message) { open class TransactionResolutionException @JvmOverloads constructor(val hash: SecureHash, message: String = "Transaction resolution failure for $hash") : FlowException(message) {
/** /**
* Thrown if a transaction specifies a set of parameters that aren't stored locally yet verification is requested. * Thrown if a transaction specifies a set of parameters that aren't stored locally yet verification is requested.
@ -35,7 +32,6 @@ open class TransactionResolutionException @JvmOverloads constructor(val hash: Se
* *
* @property hash Hash of the bytes of the attachment, see [Attachment.id] * @property hash Hash of the bytes of the attachment, see [Attachment.id]
*/ */
@KeepForDJVM
class AttachmentResolutionException(val hash: AttachmentId) : FlowException("Attachment resolution failure for $hash") class AttachmentResolutionException(val hash: AttachmentId) : FlowException("Attachment resolution failure for $hash")
/** /**
@ -43,7 +39,6 @@ class AttachmentResolutionException(val hash: AttachmentId) : FlowException("Att
* for this error is provided via the [message] and [cause]. * for this error is provided via the [message] and [cause].
* @property attachmentId * @property attachmentId
*/ */
@KeepForDJVM
class BrokenAttachmentException(val attachmentId: AttachmentId, message: String?, cause: Throwable?) class BrokenAttachmentException(val attachmentId: AttachmentId, message: String?, cause: Throwable?)
: FlowException("Attachment $attachmentId has error (${message ?: "no message"})", cause) : FlowException("Attachment $attachmentId has error (${message ?: "no message"})", cause)
@ -64,7 +59,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* *
* @property contractClass The fully qualified class name of the failing contract. * @property contractClass The fully qualified class name of the failing contract.
*/ */
@KeepForDJVM
class ContractRejection internal constructor(txId: SecureHash, val contractClass: String, cause: Throwable?, message: String) : TransactionVerificationException(txId, "Contract verification failed: $message, contract: $contractClass", cause) { class ContractRejection internal constructor(txId: SecureHash, val contractClass: String, cause: Throwable?, message: String) : TransactionVerificationException(txId, "Contract verification failed: $message, contract: $contractClass", cause) {
internal constructor(txId: SecureHash, contract: Contract, cause: Throwable) : this(txId, contract.javaClass.name, cause, cause.message ?: "") internal constructor(txId: SecureHash, contract: Contract, cause: Throwable) : this(txId, contract.javaClass.name, cause, cause.message ?: "")
} }
@ -78,7 +72,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* @property inputConstraint The constraint of the input state. * @property inputConstraint The constraint of the input state.
* @property outputConstraint The constraint of the outputs state. * @property outputConstraint The constraint of the outputs state.
*/ */
@KeepForDJVM
class ConstraintPropagationRejection(txId: SecureHash, message: String) : TransactionVerificationException(txId, message, null) { class ConstraintPropagationRejection(txId: SecureHash, message: String) : TransactionVerificationException(txId, message, null) {
constructor(txId: SecureHash, constructor(txId: SecureHash,
contractClass: String, contractClass: String,
@ -97,7 +90,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* *
* @property contractClass The fully qualified class name of the failing contract. * @property contractClass The fully qualified class name of the failing contract.
*/ */
@KeepForDJVM
class ContractConstraintRejection(txId: SecureHash, val contractClass: String) class ContractConstraintRejection(txId: SecureHash, val contractClass: String)
: TransactionVerificationException(txId, "Contract constraints failed for $contractClass", null) : TransactionVerificationException(txId, "Contract constraints failed for $contractClass", null)
@ -107,7 +99,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* @property contractClass The fully qualified class name of the failing contract. * @property contractClass The fully qualified class name of the failing contract.
* @property reason a message containing the reason the constraint is invalid included in thrown the exception. * @property reason a message containing the reason the constraint is invalid included in thrown the exception.
*/ */
@KeepForDJVM
class InvalidConstraintRejection(txId: SecureHash, val contractClass: String, val reason: String) class InvalidConstraintRejection(txId: SecureHash, val contractClass: String, val reason: String)
: TransactionVerificationException(txId, "Contract constraints failed for $contractClass. $reason", null) : TransactionVerificationException(txId, "Contract constraints failed for $contractClass. $reason", null)
@ -117,7 +108,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* *
* @property contractClass The fully qualified class name of the failing contract. * @property contractClass The fully qualified class name of the failing contract.
*/ */
@KeepForDJVM
class MissingAttachmentRejection(txId: SecureHash, val contractClass: String) class MissingAttachmentRejection(txId: SecureHash, val contractClass: String)
: TransactionVerificationException(txId, "Contract constraints failed, could not find attachment for: $contractClass", null) : TransactionVerificationException(txId, "Contract constraints failed, could not find attachment for: $contractClass", null)
@ -130,14 +120,12 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* *
* @property contractClass The fully qualified class name of the failing contract. * @property contractClass The fully qualified class name of the failing contract.
*/ */
@KeepForDJVM
class ConflictingAttachmentsRejection(txId: SecureHash, val contractClass: String) class ConflictingAttachmentsRejection(txId: SecureHash, val contractClass: String)
: TransactionVerificationException(txId, "Contract constraints failed for: $contractClass, because multiple attachments providing this contract were attached.", null) : TransactionVerificationException(txId, "Contract constraints failed for: $contractClass, because multiple attachments providing this contract were attached.", null)
/** /**
* Indicates that the same attachment has been added multiple times to a transaction. * Indicates that the same attachment has been added multiple times to a transaction.
*/ */
@KeepForDJVM
class DuplicateAttachmentsRejection(txId: SecureHash, val attachmentId: Attachment) class DuplicateAttachmentsRejection(txId: SecureHash, val attachmentId: Attachment)
: TransactionVerificationException(txId, "The attachment: $attachmentId was added multiple times.", null) : TransactionVerificationException(txId, "The attachment: $attachmentId was added multiple times.", null)
@ -147,7 +135,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* *
* @property contractClass The fully qualified class name of the failing contract. * @property contractClass The fully qualified class name of the failing contract.
*/ */
@KeepForDJVM
class ContractCreationError internal constructor(txId: SecureHash, val contractClass: String, cause: Throwable?, message: String) class ContractCreationError internal constructor(txId: SecureHash, val contractClass: String, cause: Throwable?, message: String)
: TransactionVerificationException(txId, "Contract verification failed: $message, could not create contract class: $contractClass", cause) { : TransactionVerificationException(txId, "Contract verification failed: $message, could not create contract class: $contractClass", cause) {
internal constructor(txId: SecureHash, contractClass: String, cause: Throwable) : this(txId, contractClass, cause, cause.message ?: "") internal constructor(txId: SecureHash, contractClass: String, cause: Throwable) : this(txId, contractClass, cause, cause.message ?: "")
@ -159,7 +146,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* @property txNotary the [Party] specified by the transaction header. * @property txNotary the [Party] specified by the transaction header.
* @property outputNotary the [Party] specified by the errant state. * @property outputNotary the [Party] specified by the errant state.
*/ */
@KeepForDJVM
class NotaryChangeInWrongTransactionType(txId: SecureHash, val txNotary: Party, val outputNotary: Party) class NotaryChangeInWrongTransactionType(txId: SecureHash, val txNotary: Party, val outputNotary: Party)
: TransactionVerificationException(txId, "Found unexpected notary change in transaction. Tx notary: $txNotary, found: $outputNotary", null) : TransactionVerificationException(txId, "Found unexpected notary change in transaction. Tx notary: $txNotary, found: $outputNotary", null)
@ -172,7 +158,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* @property missing the index of the state missing the encumbrance. * @property missing the index of the state missing the encumbrance.
* @property inOut whether the issue exists in the input list or output list. * @property inOut whether the issue exists in the input list or output list.
*/ */
@KeepForDJVM
class TransactionMissingEncumbranceException(txId: SecureHash, val missing: Int, val inOut: Direction) class TransactionMissingEncumbranceException(txId: SecureHash, val missing: Int, val inOut: Direction)
: TransactionVerificationException(txId, "Missing required encumbrance $missing in $inOut", null) : TransactionVerificationException(txId, "Missing required encumbrance $missing in $inOut", null)
@ -180,7 +165,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* If two or more states refer to another state (as their encumbrance), then the bi-directionality property cannot * If two or more states refer to another state (as their encumbrance), then the bi-directionality property cannot
* be satisfied. * be satisfied.
*/ */
@KeepForDJVM
class TransactionDuplicateEncumbranceException(txId: SecureHash, message: String) class TransactionDuplicateEncumbranceException(txId: SecureHash, message: String)
: TransactionVerificationException(txId, message, null) { : TransactionVerificationException(txId, message, null) {
constructor(txId: SecureHash, index: Int) : this(txId, "The bi-directionality property of encumbered output states " + constructor(txId: SecureHash, index: Int) : this(txId, "The bi-directionality property of encumbered output states " +
@ -191,7 +175,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* An encumbered state should also be referenced as the encumbrance of another state in order to satisfy the * An encumbered state should also be referenced as the encumbrance of another state in order to satisfy the
* bi-directionality property (a full cycle should be present). * bi-directionality property (a full cycle should be present).
*/ */
@KeepForDJVM
class TransactionNonMatchingEncumbranceException(txId: SecureHash, message: String) class TransactionNonMatchingEncumbranceException(txId: SecureHash, message: String)
: TransactionVerificationException(txId, message, null) { : TransactionVerificationException(txId, message, null) {
constructor(txId: SecureHash, nonMatching: Collection<Int>) : this(txId, constructor(txId: SecureHash, nonMatching: Collection<Int>) : this(txId,
@ -205,7 +188,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* transactions are not supported and thus two encumbered states with different notaries cannot be consumed * transactions are not supported and thus two encumbered states with different notaries cannot be consumed
* in the same transaction. * in the same transaction.
*/ */
@KeepForDJVM
class TransactionNotaryMismatchEncumbranceException(txId: SecureHash, message: String) class TransactionNotaryMismatchEncumbranceException(txId: SecureHash, message: String)
: TransactionVerificationException(txId, message, null) { : TransactionVerificationException(txId, message, null) {
constructor(txId: SecureHash, encumberedIndex: Int, encumbranceIndex: Int, encumberedNotary: Party, encumbranceNotary: Party) : constructor(txId: SecureHash, encumberedIndex: Int, encumbranceIndex: Int, encumberedNotary: Party, encumbranceNotary: Party) :
@ -222,7 +204,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* @param state The [TransactionState] whose bundled state and contract are in conflict. * @param state The [TransactionState] whose bundled state and contract are in conflict.
* @param requiredContractClassName The class name of the contract to which the state belongs. * @param requiredContractClassName The class name of the contract to which the state belongs.
*/ */
@KeepForDJVM
class TransactionContractConflictException(txId: SecureHash, message: String) class TransactionContractConflictException(txId: SecureHash, message: String)
: TransactionVerificationException(txId, message, null) { : TransactionVerificationException(txId, message, null) {
constructor(txId: SecureHash, state: TransactionState<ContractState>, requiredContractClassName: String): this(txId, constructor(txId: SecureHash, state: TransactionState<ContractState>, requiredContractClassName: String): this(txId,
@ -233,7 +214,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
} }
// TODO: add reference to documentation // TODO: add reference to documentation
@KeepForDJVM
class TransactionRequiredContractUnspecifiedException(txId: SecureHash, message: String) class TransactionRequiredContractUnspecifiedException(txId: SecureHash, message: String)
: TransactionVerificationException(txId, message, null) { : TransactionVerificationException(txId, message, null) {
constructor(txId: SecureHash, state: TransactionState<ContractState>) : this(txId, constructor(txId: SecureHash, state: TransactionState<ContractState>) : this(txId,
@ -247,7 +227,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
/** /**
* If the network parameters associated with an input or reference state in a transaction are more recent than the network parameters of the new transaction itself. * If the network parameters associated with an input or reference state in a transaction are more recent than the network parameters of the new transaction itself.
*/ */
@KeepForDJVM
class TransactionNetworkParameterOrderingException(txId: SecureHash, message: String) : class TransactionNetworkParameterOrderingException(txId: SecureHash, message: String) :
TransactionVerificationException(txId, message, null) { TransactionVerificationException(txId, message, null) {
constructor(txId: SecureHash, constructor(txId: SecureHash,
@ -265,7 +244,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* @param txId Id of the transaction that has missing parameters hash in the resolution chain * @param txId Id of the transaction that has missing parameters hash in the resolution chain
* @param missingNetworkParametersHash Missing hash of the network parameters associated to this transaction * @param missingNetworkParametersHash Missing hash of the network parameters associated to this transaction
*/ */
@KeepForDJVM
class MissingNetworkParametersException(txId: SecureHash, message: String) class MissingNetworkParametersException(txId: SecureHash, message: String)
: TransactionVerificationException(txId, message, null) { : TransactionVerificationException(txId, message, null) {
constructor(txId: SecureHash, missingNetworkParametersHash: SecureHash) : constructor(txId: SecureHash, missingNetworkParametersHash: SecureHash) :
@ -275,13 +253,11 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
/** /**
* @param txId Id of the transaction that Corda is no longer able to verify. * @param txId Id of the transaction that Corda is no longer able to verify.
*/ */
@KeepForDJVM
class BrokenTransactionException(txId: SecureHash, message: String) class BrokenTransactionException(txId: SecureHash, message: String)
: TransactionVerificationException(txId, message, null) : TransactionVerificationException(txId, message, null)
/** Whether the inputs or outputs list contains an encumbrance issue, see [TransactionMissingEncumbranceException]. */ /** Whether the inputs or outputs list contains an encumbrance issue, see [TransactionMissingEncumbranceException]. */
@CordaSerializable @CordaSerializable
@KeepForDJVM
enum class Direction { enum class Direction {
/** Issue in the inputs list. */ /** Issue in the inputs list. */
INPUT, INPUT,
@ -294,30 +270,25 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
// as a cause. // as a cause.
/** @suppress This class is not used: duplicate inputs throw a [IllegalStateException] instead. */ /** @suppress This class is not used: duplicate inputs throw a [IllegalStateException] instead. */
@Deprecated("This class is not used: duplicate inputs throw a [IllegalStateException] instead.") @Deprecated("This class is not used: duplicate inputs throw a [IllegalStateException] instead.")
@DeleteForDJVM
class DuplicateInputStates(txId: SecureHash, val duplicates: NonEmptySet<StateRef>) class DuplicateInputStates(txId: SecureHash, val duplicates: NonEmptySet<StateRef>)
: TransactionVerificationException(txId, "Duplicate inputs: ${duplicates.joinToString()}", null) : TransactionVerificationException(txId, "Duplicate inputs: ${duplicates.joinToString()}", null)
/** @suppress This class is obsolete and nothing has ever used it. */ /** @suppress This class is obsolete and nothing has ever used it. */
@Deprecated("This class is obsolete and nothing has ever used it.") @Deprecated("This class is obsolete and nothing has ever used it.")
@DeleteForDJVM
class MoreThanOneNotary(txId: SecureHash) : TransactionVerificationException(txId, "More than one notary", null) class MoreThanOneNotary(txId: SecureHash) : TransactionVerificationException(txId, "More than one notary", null)
/** @suppress This class is obsolete and nothing has ever used it. */ /** @suppress This class is obsolete and nothing has ever used it. */
@Deprecated("This class is obsolete and nothing has ever used it.") @Deprecated("This class is obsolete and nothing has ever used it.")
@DeleteForDJVM
class SignersMissing(txId: SecureHash, val missing: List<PublicKey>) : TransactionVerificationException(txId, "Signers missing: ${missing.joinToString()}", null) class SignersMissing(txId: SecureHash, val missing: List<PublicKey>) : TransactionVerificationException(txId, "Signers missing: ${missing.joinToString()}", null)
/** @suppress This class is obsolete and nothing has ever used it. */ /** @suppress This class is obsolete and nothing has ever used it. */
@Deprecated("This class is obsolete and nothing has ever used it.") @Deprecated("This class is obsolete and nothing has ever used it.")
@DeleteForDJVM
class InvalidNotaryChange(txId: SecureHash) class InvalidNotaryChange(txId: SecureHash)
: TransactionVerificationException(txId, "Detected a notary change. Outputs must use the same notary as inputs", null) : TransactionVerificationException(txId, "Detected a notary change. Outputs must use the same notary as inputs", null)
/** /**
* Thrown when multiple attachments provide the same file when building the AttachmentsClassloader for a transaction. * Thrown when multiple attachments provide the same file when building the AttachmentsClassloader for a transaction.
*/ */
@KeepForDJVM
class OverlappingAttachmentsException(txId: SecureHash, val path: String) : TransactionVerificationException(txId, "Multiple attachments define a file at $path.", null) class OverlappingAttachmentsException(txId: SecureHash, val path: String) : TransactionVerificationException(txId, "Multiple attachments define a file at $path.", null)
/** /**
@ -336,16 +307,12 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
// TODO: Make this descend from TransactionVerificationException so that untrusted attachments cause flows to be hospitalized. // TODO: Make this descend from TransactionVerificationException so that untrusted attachments cause flows to be hospitalized.
/** Thrown during classloading upon encountering an untrusted attachment (eg. not in the [TRUSTED_UPLOADERS] list) */ /** Thrown during classloading upon encountering an untrusted attachment (eg. not in the [TRUSTED_UPLOADERS] list) */
@KeepForDJVM
class UntrustedAttachmentsException(val txId: SecureHash, val ids: List<SecureHash>) : class UntrustedAttachmentsException(val txId: SecureHash, val ids: List<SecureHash>) :
CordaException("Attempting to load untrusted transaction attachments: $ids. " + CordaException("Attempting to load untrusted transaction attachments: $ids. " +
"At this time these are not loadable because the DJVM sandbox has not yet been integrated. " +
"You will need to manually install the CorDapp to whitelist it for use.") "You will need to manually install the CorDapp to whitelist it for use.")
@KeepForDJVM
class UnsupportedHashTypeException(txId: SecureHash) : TransactionVerificationException(txId, "The transaction Id is defined by an unsupported hash type", null) class UnsupportedHashTypeException(txId: SecureHash) : TransactionVerificationException(txId, "The transaction Id is defined by an unsupported hash type", null)
@KeepForDJVM
class AttachmentTooBigException(txId: SecureHash) : TransactionVerificationException( class AttachmentTooBigException(txId: SecureHash) : TransactionVerificationException(
txId, "The transaction attachments are too large and exceed both max transaction size and the maximum allowed compression ratio", null) txId, "The transaction attachments are too large and exceed both max transaction size and the maximum allowed compression ratio", null)

View File

@ -1,7 +1,5 @@
package net.corda.core.contracts package net.corda.core.contracts
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.VisibleForTesting
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import java.util.* import java.util.*
@ -19,8 +17,7 @@ import java.util.*
* Subsequent copies and evolutions of a state should just copy the [externalId] and [id] fields unmodified. * Subsequent copies and evolutions of a state should just copy the [externalId] and [id] fields unmodified.
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM data class UniqueIdentifier @JvmOverloads constructor(val externalId: String? = null, val id: UUID = UUID.randomUUID()) : Comparable<UniqueIdentifier> {
data class UniqueIdentifier @JvmOverloads @DeleteForDJVM constructor(val externalId: String? = null, val id: UUID = UUID.randomUUID()) : Comparable<UniqueIdentifier> {
override fun toString(): String = if (externalId != null) "${externalId}_$id" else id.toString() override fun toString(): String = if (externalId != null) "${externalId}_$id" else id.toString()
companion object { companion object {

View File

@ -1,6 +1,5 @@
package net.corda.core.cordapp package net.corda.core.cordapp
import net.corda.core.DeleteForDJVM
import net.corda.core.DoNotImplement import net.corda.core.DoNotImplement
import net.corda.core.cordapp.Cordapp.Info.* import net.corda.core.cordapp.Cordapp.Info.*
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
@ -41,7 +40,6 @@ import java.net.URL
* @property targetPlatformVersion The target platform version this CorDapp was designed and tested on. * @property targetPlatformVersion The target platform version this CorDapp was designed and tested on.
*/ */
@DoNotImplement @DoNotImplement
@DeleteForDJVM
interface Cordapp { interface Cordapp {
val name: String val name: String
val contractClassNames: List<String> val contractClassNames: List<String>

View File

@ -1,7 +1,6 @@
package net.corda.core.cordapp package net.corda.core.cordapp
import net.corda.core.CordaInternal import net.corda.core.CordaInternal
import net.corda.core.DeleteForDJVM
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import java.lang.UnsupportedOperationException import java.lang.UnsupportedOperationException
@ -18,7 +17,6 @@ import java.lang.UnsupportedOperationException
* @property classLoader the classloader used to load this cordapp's classes * @property classLoader the classloader used to load this cordapp's classes
* @property config Configuration for this CorDapp * @property config Configuration for this CorDapp
*/ */
@DeleteForDJVM
class CordappContext private constructor( class CordappContext private constructor(
val cordapp: Cordapp, val cordapp: Cordapp,
val attachmentId: SecureHash?, val attachmentId: SecureHash?,

View File

@ -1,6 +1,5 @@
package net.corda.core.cordapp package net.corda.core.cordapp
import net.corda.core.DeleteForDJVM
import net.corda.core.DoNotImplement import net.corda.core.DoNotImplement
import net.corda.core.contracts.ContractClassName import net.corda.core.contracts.ContractClassName
import net.corda.core.node.services.AttachmentId import net.corda.core.node.services.AttachmentId
@ -9,7 +8,6 @@ import net.corda.core.node.services.AttachmentId
* Provides access to what the node knows about loaded applications. * Provides access to what the node knows about loaded applications.
*/ */
@DoNotImplement @DoNotImplement
@DeleteForDJVM
interface CordappProvider { interface CordappProvider {
/** /**
* Exposes the current CorDapp context which will contain information and configuration of the CorDapp that * Exposes the current CorDapp context which will contain information and configuration of the CorDapp that

View File

@ -1,10 +1,16 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.exactAdd import net.corda.core.utilities.exactAdd
import net.corda.core.utilities.sequence import net.corda.core.utilities.sequence
import org.bouncycastle.asn1.* import org.bouncycastle.asn1.ASN1EncodableVector
import org.bouncycastle.asn1.ASN1Encoding
import org.bouncycastle.asn1.ASN1Integer
import org.bouncycastle.asn1.ASN1Object
import org.bouncycastle.asn1.ASN1Primitive
import org.bouncycastle.asn1.ASN1Sequence
import org.bouncycastle.asn1.DERBitString
import org.bouncycastle.asn1.DERSequence
import org.bouncycastle.asn1.x509.AlgorithmIdentifier import org.bouncycastle.asn1.x509.AlgorithmIdentifier
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
import java.security.PublicKey import java.security.PublicKey
@ -27,7 +33,6 @@ import java.util.*
* @property threshold specifies the minimum total weight required (in the simple case the minimum number of child * @property threshold specifies the minimum total weight required (in the simple case the minimum number of child
* signatures required) to satisfy the sub-tree rooted at this node. * signatures required) to satisfy the sub-tree rooted at this node.
*/ */
@KeepForDJVM
class CompositeKey private constructor(val threshold: Int, children: List<NodeAndWeight>) : PublicKey { class CompositeKey private constructor(val threshold: Int, children: List<NodeAndWeight>) : PublicKey {
companion object { companion object {
const val KEY_ALGORITHM = "COMPOSITE" const val KEY_ALGORITHM = "COMPOSITE"
@ -144,7 +149,6 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
* Holds node - weight pairs for a CompositeKey. Ordered first by weight, then by node's hashCode. * Holds node - weight pairs for a CompositeKey. Ordered first by weight, then by node's hashCode.
* Each node should be assigned with a positive weight to avoid certain types of weight underflow attacks. * Each node should be assigned with a positive weight to avoid certain types of weight underflow attacks.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
data class NodeAndWeight(val node: PublicKey, val weight: Int) : Comparable<NodeAndWeight>, ASN1Object() { data class NodeAndWeight(val node: PublicKey, val weight: Int) : Comparable<NodeAndWeight>, ASN1Object() {
init { init {
@ -162,7 +166,7 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
override fun toASN1Primitive(): ASN1Primitive { override fun toASN1Primitive(): ASN1Primitive {
val vector = ASN1EncodableVector() val vector = ASN1EncodableVector()
vector.add(DERBitString(node.encoded)) vector.add(DERBitString(Crypto.encodePublicKey(node)))
vector.add(ASN1Integer(weight.toLong())) vector.add(ASN1Integer(weight.toLong()))
return DERSequence(vector) return DERSequence(vector)
} }
@ -243,7 +247,6 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
override fun toString() = "(${children.joinToString()})" override fun toString() = "(${children.joinToString()})"
/** A helper class for building a [CompositeKey]. */ /** A helper class for building a [CompositeKey]. */
@KeepForDJVM
class Builder { class Builder {
private val children: MutableList<NodeAndWeight> = mutableListOf() private val children: MutableList<NodeAndWeight> = mutableListOf()

View File

@ -1,6 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import java.security.* import java.security.*
import java.security.spec.InvalidKeySpecException import java.security.spec.InvalidKeySpecException
import java.security.spec.KeySpec import java.security.spec.KeySpec
@ -9,7 +8,6 @@ import java.security.spec.X509EncodedKeySpec
/** /**
* Factory for generating composite keys from ASN.1 format key specifications. This is used by [CordaSecurityProvider]. * Factory for generating composite keys from ASN.1 format key specifications. This is used by [CordaSecurityProvider].
*/ */
@KeepForDJVM
class CompositeKeyFactory : KeyFactorySpi() { class CompositeKeyFactory : KeyFactorySpi() {
@Throws(InvalidKeySpecException::class) @Throws(InvalidKeySpecException::class)

View File

@ -1,6 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.security.InvalidAlgorithmParameterException import java.security.InvalidAlgorithmParameterException
@ -15,7 +14,6 @@ import java.security.spec.AlgorithmParameterSpec
/** /**
* Dedicated class for storing a set of signatures that comprise [CompositeKey]. * Dedicated class for storing a set of signatures that comprise [CompositeKey].
*/ */
@KeepForDJVM
class CompositeSignature : Signature(SIGNATURE_ALGORITHM) { class CompositeSignature : Signature(SIGNATURE_ALGORITHM) {
companion object { companion object {
const val SIGNATURE_ALGORITHM = "COMPOSITESIG" const val SIGNATURE_ALGORITHM = "COMPOSITESIG"

View File

@ -1,6 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
/** /**
@ -8,7 +7,6 @@ import net.corda.core.serialization.CordaSerializable
* serialization format. * serialization format.
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM
data class CompositeSignaturesWithKeys(val sigs: List<TransactionSignature>) { data class CompositeSignaturesWithKeys(val sigs: List<TransactionSignature>) {
companion object { companion object {
val EMPTY = CompositeSignaturesWithKeys(emptyList()) val EMPTY = CompositeSignaturesWithKeys(emptyList())

View File

@ -1,7 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import net.corda.core.StubOutForDJVM
import net.corda.core.crypto.CordaObjectIdentifier.COMPOSITE_KEY import net.corda.core.crypto.CordaObjectIdentifier.COMPOSITE_KEY
import net.corda.core.crypto.CordaObjectIdentifier.COMPOSITE_SIGNATURE import net.corda.core.crypto.CordaObjectIdentifier.COMPOSITE_SIGNATURE
import net.corda.core.crypto.internal.PlatformSecureRandomService import net.corda.core.crypto.internal.PlatformSecureRandomService
@ -10,13 +8,14 @@ import java.security.Provider
import java.util.* import java.util.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@KeepForDJVM
@Suppress("DEPRECATION") // JDK11: should replace with Provider(String name, double version, String info) (since 9) @Suppress("DEPRECATION") // JDK11: should replace with Provider(String name, double version, String info) (since 9)
class CordaSecurityProvider : Provider(PROVIDER_NAME, 0.1, "$PROVIDER_NAME security provider wrapper") { class CordaSecurityProvider : Provider(PROVIDER_NAME, 0.1, "$PROVIDER_NAME security provider wrapper") {
companion object { companion object {
const val PROVIDER_NAME = "Corda" const val PROVIDER_NAME = "Corda"
} }
private val services = ConcurrentHashMap<Pair<String, String>, Optional<Service>>()
init { init {
put("KeyFactory.${CompositeKey.KEY_ALGORITHM}", CompositeKeyFactory::class.java.name) put("KeyFactory.${CompositeKey.KEY_ALGORITHM}", CompositeKeyFactory::class.java.name)
put("Alg.Alias.KeyFactory.$COMPOSITE_KEY", CompositeKey.KEY_ALGORITHM) put("Alg.Alias.KeyFactory.$COMPOSITE_KEY", CompositeKey.KEY_ALGORITHM)
@ -27,47 +26,19 @@ class CordaSecurityProvider : Provider(PROVIDER_NAME, 0.1, "$PROVIDER_NAME secur
putPlatformSecureRandomService() putPlatformSecureRandomService()
} }
@StubOutForDJVM
private fun putPlatformSecureRandomService() { private fun putPlatformSecureRandomService() {
putService(PlatformSecureRandomService(this)) putService(PlatformSecureRandomService(this))
} }
override fun getService(type: String, algorithm: String): Service? = serviceFactory(type, algorithm) override fun getService(type: String, algorithm: String): Service? {
return services.getOrPut(Pair(type, algorithm)) {
// Used to work around banning of ConcurrentHashMap in DJVM Optional.ofNullable(superGetService(type, algorithm))
@Suppress("TooGenericExceptionCaught") }.orElse(null)
private val serviceFactory: (String, String) -> Service? = try {
// Will throw UnsupportedOperationException in DJVM
makeCachingFactory()
} catch (e: Exception) {
makeFactory()
} }
private fun superGetService(type: String, algorithm: String): Service? = super.getService(type, algorithm) private fun superGetService(type: String, algorithm: String): Service? = super.getService(type, algorithm)
@StubOutForDJVM
private fun makeCachingFactory(): Function2<String, String, Service?> {
return object : Function2<String, String, Service?> {
private val services = ConcurrentHashMap<Pair<String, String>, Optional<Service>>()
override fun invoke(type: String, algorithm: String): Service? {
return services.getOrPut(Pair(type, algorithm)) {
Optional.ofNullable(superGetService(type, algorithm))
}.orElse(null)
}
}
}
private fun makeFactory(): Function2<String, String, Service?> {
return object : Function2<String, String, Service?> {
override fun invoke(type: String, algorithm: String): Service? {
return superGetService(type, algorithm)
}
}
}
} }
@KeepForDJVM
object CordaObjectIdentifier { object CordaObjectIdentifier {
// UUID-based OID // UUID-based OID
// TODO define and use an official Corda OID in [CordaOID]. We didn't do yet for backwards compatibility purposes, // TODO define and use an official Corda OID in [CordaOID]. We didn't do yet for backwards compatibility purposes,

View File

@ -1,10 +1,9 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.CordaOID import net.corda.core.CordaOID
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.crypto.internal.AliasPrivateKey import net.corda.core.crypto.internal.AliasPrivateKey
import net.corda.core.crypto.internal.Instances.withSignature import net.corda.core.crypto.internal.Instances.withSignature
import net.corda.core.crypto.internal.PublicKeyCache
import net.corda.core.crypto.internal.bouncyCastlePQCProvider import net.corda.core.crypto.internal.bouncyCastlePQCProvider
import net.corda.core.crypto.internal.cordaBouncyCastleProvider import net.corda.core.crypto.internal.cordaBouncyCastleProvider
import net.corda.core.crypto.internal.cordaSecurityProvider import net.corda.core.crypto.internal.cordaSecurityProvider
@ -12,6 +11,7 @@ import net.corda.core.crypto.internal.`id-Curve25519ph`
import net.corda.core.crypto.internal.providerMap import net.corda.core.crypto.internal.providerMap
import net.corda.core.internal.utilities.PrivateInterner import net.corda.core.internal.utilities.PrivateInterner
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.ByteSequence
import net.i2p.crypto.eddsa.EdDSAEngine import net.i2p.crypto.eddsa.EdDSAEngine
import net.i2p.crypto.eddsa.EdDSAPrivateKey import net.i2p.crypto.eddsa.EdDSAPrivateKey
import net.i2p.crypto.eddsa.EdDSAPublicKey import net.i2p.crypto.eddsa.EdDSAPublicKey
@ -81,7 +81,6 @@ import javax.crypto.spec.SecretKeySpec
* <li>SPHINCS256_SHA512 (SPHINCS-256 hash-based signature scheme using SHA512 as hash algorithm). * <li>SPHINCS256_SHA512 (SPHINCS-256 hash-based signature scheme using SHA512 as hash algorithm).
* </ul> * </ul>
*/ */
@KeepForDJVM
object Crypto { object Crypto {
/** /**
* RSA PKCS#1 signature scheme using SHA256 for message hashing. * RSA PKCS#1 signature scheme using SHA256 for message hashing.
@ -227,7 +226,6 @@ object Crypto {
@JvmStatic @JvmStatic
fun supportedSignatureSchemes(): List<SignatureScheme> = ArrayList(signatureSchemeMap.values) fun supportedSignatureSchemes(): List<SignatureScheme> = ArrayList(signatureSchemeMap.values)
@DeleteForDJVM
@JvmStatic @JvmStatic
fun findProvider(name: String): Provider { fun findProvider(name: String): Provider {
return providerMap[name] ?: throw IllegalArgumentException("Unrecognised provider: $name") return providerMap[name] ?: throw IllegalArgumentException("Unrecognised provider: $name")
@ -281,7 +279,7 @@ object Crypto {
*/ */
@JvmStatic @JvmStatic
fun findSignatureScheme(key: PublicKey): SignatureScheme { fun findSignatureScheme(key: PublicKey): SignatureScheme {
val keyInfo = SubjectPublicKeyInfo.getInstance(key.encoded) val keyInfo = SubjectPublicKeyInfo.getInstance(encodePublicKey(key))
return findSignatureScheme(keyInfo.algorithm) return findSignatureScheme(keyInfo.algorithm)
} }
@ -306,7 +304,6 @@ object Crypto {
* @throws IllegalArgumentException on not supported scheme or if the given key specification * @throws IllegalArgumentException on not supported scheme or if the given key specification
* is inappropriate for this key factory to produce a private key. * is inappropriate for this key factory to produce a private key.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun decodePrivateKey(encodedKey: ByteArray): PrivateKey { fun decodePrivateKey(encodedKey: ByteArray): PrivateKey {
val keyInfo = PrivateKeyInfo.getInstance(encodedKey) val keyInfo = PrivateKeyInfo.getInstance(encodedKey)
@ -318,7 +315,6 @@ object Crypto {
return convertIfBCEdDSAPrivateKey(keyFactory.generatePrivate(PKCS8EncodedKeySpec(encodedKey))) return convertIfBCEdDSAPrivateKey(keyFactory.generatePrivate(PKCS8EncodedKeySpec(encodedKey)))
} }
@DeleteForDJVM
private fun decodeAliasPrivateKey(keyInfo: PrivateKeyInfo): PrivateKey { private fun decodeAliasPrivateKey(keyInfo: PrivateKeyInfo): PrivateKey {
val encodable = keyInfo.parsePrivateKey() as DLSequence val encodable = keyInfo.parsePrivateKey() as DLSequence
val derutF8String = encodable.getObjectAt(0) val derutF8String = encodable.getObjectAt(0)
@ -334,7 +330,6 @@ object Crypto {
* @throws IllegalArgumentException on not supported scheme or if the given key specification * @throws IllegalArgumentException on not supported scheme or if the given key specification
* is inappropriate for this key factory to produce a private key. * is inappropriate for this key factory to produce a private key.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
@Throws(InvalidKeySpecException::class) @Throws(InvalidKeySpecException::class)
fun decodePrivateKey(schemeCodeName: String, encodedKey: ByteArray): PrivateKey { fun decodePrivateKey(schemeCodeName: String, encodedKey: ByteArray): PrivateKey {
@ -373,10 +368,17 @@ object Crypto {
*/ */
@JvmStatic @JvmStatic
fun decodePublicKey(encodedKey: ByteArray): PublicKey { fun decodePublicKey(encodedKey: ByteArray): PublicKey {
val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(encodedKey) return PublicKeyCache.publicKeyForCachedBytes(ByteSequence.of(encodedKey)) ?: {
val signatureScheme = findSignatureScheme(subjectPublicKeyInfo.algorithm) val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(encodedKey)
val keyFactory = keyFactory(signatureScheme) val signatureScheme = findSignatureScheme(subjectPublicKeyInfo.algorithm)
return convertIfBCEdDSAPublicKey(keyFactory.generatePublic(X509EncodedKeySpec(encodedKey))) val keyFactory = keyFactory(signatureScheme)
convertIfBCEdDSAPublicKey(keyFactory.generatePublic(X509EncodedKeySpec(encodedKey)))
}()
}
@JvmStatic
fun encodePublicKey(key: PublicKey): ByteArray {
return PublicKeyCache.bytesForCachedPublicKey(key)?.bytes ?: key.encoded
} }
/** /**
@ -429,7 +431,6 @@ object Crypto {
* @throws InvalidKeyException if the private key is invalid. * @throws InvalidKeyException if the private key is invalid.
* @throws SignatureException if signing is not possible due to malformed data or private key. * @throws SignatureException if signing is not possible due to malformed data or private key.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
@Throws(InvalidKeyException::class, SignatureException::class) @Throws(InvalidKeyException::class, SignatureException::class)
fun doSign(privateKey: PrivateKey, clearData: ByteArray): ByteArray = doSign(findSignatureScheme(privateKey), privateKey, clearData) fun doSign(privateKey: PrivateKey, clearData: ByteArray): ByteArray = doSign(findSignatureScheme(privateKey), privateKey, clearData)
@ -444,7 +445,6 @@ object Crypto {
* @throws InvalidKeyException if the private key is invalid. * @throws InvalidKeyException if the private key is invalid.
* @throws SignatureException if signing is not possible due to malformed data or private key. * @throws SignatureException if signing is not possible due to malformed data or private key.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
@Throws(InvalidKeyException::class, SignatureException::class) @Throws(InvalidKeyException::class, SignatureException::class)
fun doSign(schemeCodeName: String, privateKey: PrivateKey, clearData: ByteArray): ByteArray { fun doSign(schemeCodeName: String, privateKey: PrivateKey, clearData: ByteArray): ByteArray {
@ -461,7 +461,6 @@ object Crypto {
* @throws InvalidKeyException if the private key is invalid. * @throws InvalidKeyException if the private key is invalid.
* @throws SignatureException if signing is not possible due to malformed data or private key. * @throws SignatureException if signing is not possible due to malformed data or private key.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
@Throws(InvalidKeyException::class, SignatureException::class) @Throws(InvalidKeyException::class, SignatureException::class)
fun doSign(signatureScheme: SignatureScheme, privateKey: PrivateKey, clearData: ByteArray): ByteArray { fun doSign(signatureScheme: SignatureScheme, privateKey: PrivateKey, clearData: ByteArray): ByteArray {
@ -501,7 +500,6 @@ object Crypto {
* @throws InvalidKeyException if the private key is invalid. * @throws InvalidKeyException if the private key is invalid.
* @throws SignatureException if signing is not possible due to malformed data or private key. * @throws SignatureException if signing is not possible due to malformed data or private key.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
@Throws(InvalidKeyException::class, SignatureException::class) @Throws(InvalidKeyException::class, SignatureException::class)
fun doSign(keyPair: KeyPair, signableData: SignableData): TransactionSignature { fun doSign(keyPair: KeyPair, signableData: SignableData): TransactionSignature {
@ -688,7 +686,6 @@ object Crypto {
* @return a KeyPair for the requested signature scheme code name. * @return a KeyPair for the requested signature scheme code name.
* @throws IllegalArgumentException if the requested signature scheme is not supported. * @throws IllegalArgumentException if the requested signature scheme is not supported.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun generateKeyPair(schemeCodeName: String): KeyPair = generateKeyPair(findSignatureScheme(schemeCodeName)) fun generateKeyPair(schemeCodeName: String): KeyPair = generateKeyPair(findSignatureScheme(schemeCodeName))
@ -699,7 +696,6 @@ object Crypto {
* @return a new [KeyPair] for the requested [SignatureScheme]. * @return a new [KeyPair] for the requested [SignatureScheme].
* @throws IllegalArgumentException if the requested signature scheme is not supported. * @throws IllegalArgumentException if the requested signature scheme is not supported.
*/ */
@DeleteForDJVM
@JvmOverloads @JvmOverloads
@JvmStatic @JvmStatic
fun generateKeyPair(signatureScheme: SignatureScheme = DEFAULT_SIGNATURE_SCHEME): KeyPair { fun generateKeyPair(signatureScheme: SignatureScheme = DEFAULT_SIGNATURE_SCHEME): KeyPair {
@ -993,7 +989,8 @@ object Crypto {
} }
private val interner = PrivateInterner<PublicKey>() private val interner = PrivateInterner<PublicKey>()
private fun internPublicKey(key: PublicKey): PublicKey = interner.intern(key) private fun internPublicKey(key: PublicKey): PublicKey = PublicKeyCache.cachePublicKey(interner.intern(key))
private fun convertIfBCEdDSAPublicKey(key: PublicKey): PublicKey { private fun convertIfBCEdDSAPublicKey(key: PublicKey): PublicKey {
return internPublicKey(when (key) { return internPublicKey(when (key) {
@ -1049,7 +1046,6 @@ object Crypto {
* @throws IllegalArgumentException on not supported scheme or if the given key specification * @throws IllegalArgumentException on not supported scheme or if the given key specification
* is inappropriate for a supported key factory to produce a private key. * is inappropriate for a supported key factory to produce a private key.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun toSupportedPrivateKey(key: PrivateKey): PrivateKey { fun toSupportedPrivateKey(key: PrivateKey): PrivateKey {
return when (key) { return when (key) {
@ -1086,7 +1082,6 @@ object Crypto {
* CRL & CSR checks etc.). * CRL & CSR checks etc.).
*/ */
// TODO: perform all cryptographic operations via Crypto. // TODO: perform all cryptographic operations via Crypto.
@DeleteForDJVM
@JvmStatic @JvmStatic
fun registerProviders() { fun registerProviders() {
providerMap providerMap
@ -1097,7 +1092,6 @@ object Crypto {
setBouncyCastleRNG() setBouncyCastleRNG()
} }
@DeleteForDJVM
private fun setBouncyCastleRNG() { private fun setBouncyCastleRNG() {
CryptoServicesRegistrar.setSecureRandom(newSecureRandom()) CryptoServicesRegistrar.setSecureRandom(newSecureRandom())
} }

View File

@ -1,11 +1,7 @@
@file:Suppress("MatchingDeclarationName") @file:Suppress("MatchingDeclarationName")
@file:KeepForDJVM
@file:JvmName("CryptoUtils") @file:JvmName("CryptoUtils")
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.contracts.PrivacySalt import net.corda.core.contracts.PrivacySalt
import net.corda.core.crypto.internal.platformSecureRandomFactory import net.corda.core.crypto.internal.platformSecureRandomFactory
import net.corda.core.serialization.SerializationDefaults import net.corda.core.serialization.SerializationDefaults
@ -32,7 +28,6 @@ import java.security.SignatureException
* @throws InvalidKeyException if the private key is invalid. * @throws InvalidKeyException if the private key is invalid.
* @throws SignatureException if signing is not possible due to malformed data or private key. * @throws SignatureException if signing is not possible due to malformed data or private key.
*/ */
@DeleteForDJVM
@Throws(InvalidKeyException::class, SignatureException::class) @Throws(InvalidKeyException::class, SignatureException::class)
fun PrivateKey.sign(bytesToSign: ByteArray): DigitalSignature = DigitalSignature(Crypto.doSign(this, bytesToSign)) fun PrivateKey.sign(bytesToSign: ByteArray): DigitalSignature = DigitalSignature(Crypto.doSign(this, bytesToSign))
@ -45,7 +40,6 @@ fun PrivateKey.sign(bytesToSign: ByteArray): DigitalSignature = DigitalSignature
* @throws InvalidKeyException if the private key is invalid. * @throws InvalidKeyException if the private key is invalid.
* @throws SignatureException if signing is not possible due to malformed data or private key. * @throws SignatureException if signing is not possible due to malformed data or private key.
*/ */
@DeleteForDJVM
@Throws(InvalidKeyException::class, SignatureException::class) @Throws(InvalidKeyException::class, SignatureException::class)
fun PrivateKey.sign(bytesToSign: ByteArray, publicKey: PublicKey): DigitalSignature.WithKey { fun PrivateKey.sign(bytesToSign: ByteArray, publicKey: PublicKey): DigitalSignature.WithKey {
return DigitalSignature.WithKey(publicKey, this.sign(bytesToSign).bytes) return DigitalSignature.WithKey(publicKey, this.sign(bytesToSign).bytes)
@ -59,12 +53,10 @@ fun PrivateKey.sign(bytesToSign: ByteArray, publicKey: PublicKey): DigitalSignat
* @throws InvalidKeyException if the private key is invalid. * @throws InvalidKeyException if the private key is invalid.
* @throws SignatureException if signing is not possible due to malformed data or private key. * @throws SignatureException if signing is not possible due to malformed data or private key.
*/ */
@DeleteForDJVM
@Throws(InvalidKeyException::class, SignatureException::class) @Throws(InvalidKeyException::class, SignatureException::class)
fun KeyPair.sign(bytesToSign: ByteArray): DigitalSignature.WithKey = private.sign(bytesToSign, public) fun KeyPair.sign(bytesToSign: ByteArray): DigitalSignature.WithKey = private.sign(bytesToSign, public)
/** Helper function to sign the bytes of [bytesToSign] with a key pair. */ /** Helper function to sign the bytes of [bytesToSign] with a key pair. */
@DeleteForDJVM
@Throws(InvalidKeyException::class, SignatureException::class) @Throws(InvalidKeyException::class, SignatureException::class)
fun KeyPair.sign(bytesToSign: OpaqueBytes): DigitalSignature.WithKey = sign(bytesToSign.bytes) fun KeyPair.sign(bytesToSign: OpaqueBytes): DigitalSignature.WithKey = sign(bytesToSign.bytes)
@ -76,7 +68,6 @@ fun KeyPair.sign(bytesToSign: OpaqueBytes): DigitalSignature.WithKey = sign(byte
* @throws InvalidKeyException if the private key is invalid. * @throws InvalidKeyException if the private key is invalid.
* @throws SignatureException if signing is not possible due to malformed data or private key. * @throws SignatureException if signing is not possible due to malformed data or private key.
*/ */
@DeleteForDJVM
@Throws(InvalidKeyException::class, SignatureException::class) @Throws(InvalidKeyException::class, SignatureException::class)
fun KeyPair.sign(signableData: SignableData): TransactionSignature = Crypto.doSign(this, signableData) fun KeyPair.sign(signableData: SignableData): TransactionSignature = Crypto.doSign(this, signableData)
@ -151,7 +142,6 @@ operator fun KeyPair.component1(): PrivateKey = this.private
operator fun KeyPair.component2(): PublicKey = this.public operator fun KeyPair.component2(): PublicKey = this.public
/** A simple wrapper that will make it easier to swap out the signature algorithm we use in future. */ /** A simple wrapper that will make it easier to swap out the signature algorithm we use in future. */
@DeleteForDJVM
fun generateKeyPair(): KeyPair = Crypto.generateKeyPair() fun generateKeyPair(): KeyPair = Crypto.generateKeyPair()
/** /**
@ -196,7 +186,6 @@ fun KeyPair.verify(signatureData: ByteArray, clearData: ByteArray): Boolean = Cr
* or if no strong [SecureRandom] implementations are available or if Security.getProperty("securerandom.strongAlgorithms") is null or empty, * or if no strong [SecureRandom] implementations are available or if Security.getProperty("securerandom.strongAlgorithms") is null or empty,
* which should never happen and suggests an unusual JVM or non-standard Java library. * which should never happen and suggests an unusual JVM or non-standard Java library.
*/ */
@DeleteForDJVM
@Throws(NoSuchAlgorithmException::class) @Throws(NoSuchAlgorithmException::class)
fun secureRandomBytes(numOfBytes: Int): ByteArray = ByteArray(numOfBytes).apply { newSecureRandom().nextBytes(this) } fun secureRandomBytes(numOfBytes: Int): ByteArray = ByteArray(numOfBytes).apply { newSecureRandom().nextBytes(this) }
@ -241,7 +230,6 @@ object DummySecureRandom : SecureRandom(DummySecureRandomSpi(), null)
* or if no strong SecureRandom implementations are available or if Security.getProperty("securerandom.strongAlgorithms") is null or empty, * or if no strong SecureRandom implementations are available or if Security.getProperty("securerandom.strongAlgorithms") is null or empty,
* which should never happen and suggests an unusual JVM or non-standard Java library. * which should never happen and suggests an unusual JVM or non-standard Java library.
*/ */
@DeleteForDJVM
@Throws(NoSuchAlgorithmException::class) @Throws(NoSuchAlgorithmException::class)
fun newSecureRandom(): SecureRandom = platformSecureRandomFactory() fun newSecureRandom(): SecureRandom = platformSecureRandomFactory()
@ -249,7 +237,6 @@ fun newSecureRandom(): SecureRandom = platformSecureRandomFactory()
* Returns a random positive non-zero long generated using a secure RNG. This function sacrifies a bit of entropy in order * Returns a random positive non-zero long generated using a secure RNG. This function sacrifies a bit of entropy in order
* to avoid potential bugs where the value is used in a context where negative numbers or zero are not expected. * to avoid potential bugs where the value is used in a context where negative numbers or zero are not expected.
*/ */
@DeleteForDJVM
fun random63BitValue(): Long { fun random63BitValue(): Long {
while (true) { while (true) {
val candidate = Math.abs(newSecureRandom().nextLong()) val candidate = Math.abs(newSecureRandom().nextLong())

View File

@ -1,11 +1,8 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
/** /**
* Interface for injecting custom digest implementation bypassing JCA. * Interface for injecting custom digest implementation bypassing JCA.
*/ */
@KeepForDJVM
interface DigestAlgorithm { interface DigestAlgorithm {
/** /**
* Algorithm identifier. * Algorithm identifier.

View File

@ -1,7 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.contracts.PrivacySalt import net.corda.core.contracts.PrivacySalt
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializationDefaults import net.corda.core.serialization.SerializationDefaults
@ -24,13 +22,11 @@ import java.security.MessageDigest
* @param hashAlgorithm the name of the hash algorithm to be used for the instance * @param hashAlgorithm the name of the hash algorithm to be used for the instance
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM
data class DigestService(val hashAlgorithm: String) { data class DigestService(val hashAlgorithm: String) {
init { init {
require(hashAlgorithm.isNotEmpty()) { "Hash algorithm name unavailable or not specified" } require(hashAlgorithm.isNotEmpty()) { "Hash algorithm name unavailable or not specified" }
} }
@KeepForDJVM
companion object { companion object {
private const val NONCE_SIZE = 8 private const val NONCE_SIZE = 8
/** /**
@ -114,5 +110,4 @@ data class DigestService(val hashAlgorithm: String) {
} }
} }
@DeleteForDJVM
fun DigestService.randomHash(): SecureHash = SecureHash.random(this.hashAlgorithm) fun DigestService.randomHash(): SecureHash = SecureHash.random(this.hashAlgorithm)

View File

@ -1,6 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import java.security.InvalidKeyException import java.security.InvalidKeyException
@ -9,10 +8,8 @@ import java.security.SignatureException
/** A wrapper around a digital signature. */ /** A wrapper around a digital signature. */
@CordaSerializable @CordaSerializable
@KeepForDJVM
open class DigitalSignature(bytes: ByteArray) : OpaqueBytes(bytes) { open class DigitalSignature(bytes: ByteArray) : OpaqueBytes(bytes) {
/** A digital signature that identifies who the public key is owned by. */ /** A digital signature that identifies who the public key is owned by. */
@KeepForDJVM
open class WithKey(val by: PublicKey, bytes: ByteArray) : DigitalSignature(bytes) { open class WithKey(val by: PublicKey, bytes: ByteArray) : DigitalSignature(bytes) {
/** /**
* Utility to simplify the act of verifying a signature. * Utility to simplify the act of verifying a signature.

View File

@ -1,6 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import java.util.* import java.util.*
/** /**
@ -15,8 +14,9 @@ import java.util.*
sealed class MerkleTree { sealed class MerkleTree {
abstract val hash: SecureHash abstract val hash: SecureHash
@KeepForDJVM data class Leaf(override val hash: SecureHash) : MerkleTree() data class Leaf(override val hash: SecureHash) : MerkleTree()
@KeepForDJVM data class Node(override val hash: SecureHash, val left: MerkleTree, val right: MerkleTree) : MerkleTree()
data class Node(override val hash: SecureHash, val left: MerkleTree, val right: MerkleTree) : MerkleTree()
companion object { companion object {
private fun isPow2(num: Int): Boolean = num and (num - 1) == 0 private fun isPow2(num: Int): Boolean = num and (num - 1) == 0

View File

@ -1,10 +1,8 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
import java.security.PublicKey import java.security.PublicKey
@KeepForDJVM
object NullKeys { object NullKeys {
object NullPublicKey : PublicKey, Comparable<PublicKey> { object NullPublicKey : PublicKey, Comparable<PublicKey> {
override fun getAlgorithm() = "NULL" override fun getAlgorithm() = "NULL"

View File

@ -2,12 +2,10 @@ package net.corda.core.crypto
import net.corda.core.CordaException import net.corda.core.CordaException
import net.corda.core.CordaInternal import net.corda.core.CordaInternal
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.DeprecatedConstructorForDeserialization import net.corda.core.serialization.DeprecatedConstructorForDeserialization
import java.util.* import java.util.*
@KeepForDJVM
@CordaSerializable @CordaSerializable
class MerkleTreeException(val reason: String) : CordaException("Partial Merkle Tree exception. Reason: $reason") class MerkleTreeException(val reason: String) : CordaException("Partial Merkle Tree exception. Reason: $reason")
@ -45,7 +43,6 @@ class MerkleTreeException(val reason: String) : CordaException("Partial Merkle T
* (there can be a difference in obtained leaves ordering - that's why it's a set comparison not hashing leaves into a tree). * (there can be a difference in obtained leaves ordering - that's why it's a set comparison not hashing leaves into a tree).
* If both equalities hold, we can assume that l3 and l5 belong to the transaction with root h15. * If both equalities hold, we can assume that l3 and l5 belong to the transaction with root h15.
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
class PartialMerkleTree(val root: PartialTree) { class PartialMerkleTree(val root: PartialTree) {
/** /**
@ -57,9 +54,9 @@ class PartialMerkleTree(val root: PartialTree) {
*/ */
@CordaSerializable @CordaSerializable
sealed class PartialTree { sealed class PartialTree {
@KeepForDJVM data class IncludedLeaf(val hash: SecureHash) : PartialTree() data class IncludedLeaf(val hash: SecureHash) : PartialTree()
@KeepForDJVM data class Leaf(val hash: SecureHash) : PartialTree() data class Leaf(val hash: SecureHash) : PartialTree()
@KeepForDJVM data class Node(val left: PartialTree, val right: PartialTree, val hashAlgorithm: String? = SecureHash.SHA2_256) : PartialTree(){ data class Node(val left: PartialTree, val right: PartialTree, val hashAlgorithm: String? = SecureHash.SHA2_256) : PartialTree() {
/** /**
* Old version of [PartialTree.Node] constructor for ABI compatibility. * Old version of [PartialTree.Node] constructor for ABI compatibility.
*/ */

View File

@ -1,11 +1,8 @@
@file:Suppress("TooManyFunctions", "MagicNumber") @file:Suppress("TooManyFunctions", "MagicNumber")
@file:KeepForDJVM
package net.corda.core.crypto package net.corda.core.crypto
import io.netty.util.concurrent.FastThreadLocal import io.netty.util.concurrent.FastThreadLocal
import net.corda.core.CordaInternal 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.crypto.internal.DigestAlgorithmFactory
import net.corda.core.internal.utilities.Internable import net.corda.core.internal.utilities.Internable
import net.corda.core.internal.utilities.PrivateInterner import net.corda.core.internal.utilities.PrivateInterner
@ -13,7 +10,6 @@ import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.parseAsHex import net.corda.core.utilities.parseAsHex
import net.corda.core.utilities.toHexString import net.corda.core.utilities.toHexString
import java.nio.ByteBuffer
import java.security.MessageDigest import java.security.MessageDigest
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap import java.util.concurrent.ConcurrentMap
@ -23,7 +19,6 @@ import java.util.function.Supplier
* Container for a cryptographically secure hash value. * Container for a cryptographically secure hash value.
* Provides utilities for generating a cryptographic hash using different algorithms (currently only SHA-256 supported). * Provides utilities for generating a cryptographic hash using different algorithms (currently only SHA-256 supported).
*/ */
@KeepForDJVM
@CordaSerializable @CordaSerializable
sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) { sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
/** SHA-256 is part of the SHA-2 hash function family. Generated hash is fixed size, 256-bits (32-bytes). */ /** SHA-256 is part of the SHA-2 hash function family. Generated hash is fixed size, 256-bits (32-bytes). */
@ -39,9 +34,10 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
return true return true
} }
// This is an efficient hashCode, because there is no point in performing a hash calculation on a cryptographic hash. override fun hashCode(): Int {
// It just takes the first 4 bytes and transforms them into an Int. // Hash code not overridden on purpose (super class impl will do), but don't delete or have to deal with detekt and API checker.
override fun hashCode() = ByteBuffer.wrap(bytes).int return super.hashCode()
}
/** /**
* Convert the hash value to an uppercase hexadecimal [String]. * Convert the hash value to an uppercase hexadecimal [String].
@ -62,7 +58,10 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
} }
} }
override fun hashCode() = ByteBuffer.wrap(bytes).int override fun hashCode(): Int {
// Hash code not overridden on purpose (super class impl will do), but don't delete or have to deal with detekt and API checker.
return super.hashCode()
}
override fun toString(): String { override fun toString(): String {
return "$algorithm$DELIMITER${toHexString()}" return "$algorithm$DELIMITER${toHexString()}"
@ -288,14 +287,12 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
/** /**
* Generates a random SHA-256 value. * Generates a random SHA-256 value.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun randomSHA256() = sha256(secureRandomBytes(32)) fun randomSHA256() = sha256(secureRandomBytes(32))
/** /**
* Generates a random hash value. * Generates a random hash value.
*/ */
@DeleteForDJVM
@JvmStatic @JvmStatic
fun random(algorithm: String): SecureHash { fun random(algorithm: String): SecureHash {
return if (algorithm == SHA2_256) { return if (algorithm == SHA2_256) {

View File

@ -1,6 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
/** /**
@ -13,5 +12,4 @@ import net.corda.core.serialization.CordaSerializable
* @param signatureMetadata meta data required. * @param signatureMetadata meta data required.
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM
data class SignableData(val txId: SecureHash, val signatureMetadata: SignatureMetadata) data class SignableData(val txId: SecureHash, val signatureMetadata: SignatureMetadata)

View File

@ -1,6 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
/** /**
@ -13,5 +12,4 @@ import net.corda.core.serialization.CordaSerializable
* @param schemeNumberID number id of the signature scheme used based on signer's key-pair, see [SignatureScheme.schemeNumberID]. * @param schemeNumberID number id of the signature scheme used based on signer's key-pair, see [SignatureScheme.schemeNumberID].
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM
data class SignatureMetadata(val platformVersion: Int, val schemeNumberID: Int) data class SignatureMetadata(val platformVersion: Int, val schemeNumberID: Int)

View File

@ -1,6 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import org.bouncycastle.asn1.x509.AlgorithmIdentifier import org.bouncycastle.asn1.x509.AlgorithmIdentifier
import java.security.KeyFactory import java.security.KeyFactory
import java.security.Signature import java.security.Signature
@ -22,7 +21,6 @@ import java.security.spec.AlgorithmParameterSpec
* @param keySize the private key size (currently used for RSA only). * @param keySize the private key size (currently used for RSA only).
* @param desc a human-readable description for this scheme. * @param desc a human-readable description for this scheme.
*/ */
@KeepForDJVM
data class SignatureScheme( data class SignatureScheme(
val schemeNumberID: Int, val schemeNumberID: Int,
val schemeCodeName: String, val schemeCodeName: String,

View File

@ -1,6 +1,5 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.KeepForDJVM
import net.corda.core.internal.uncheckedCast import net.corda.core.internal.uncheckedCast
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
@ -15,7 +14,6 @@ import java.security.SignatureException
* @param sig the (unverified) signature for the data. * @param sig the (unverified) signature for the data.
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM
open class SignedData<T : Any>(val raw: SerializedBytes<T>, val sig: DigitalSignature.WithKey) { open class SignedData<T : Any>(val raw: SerializedBytes<T>, val sig: DigitalSignature.WithKey) {
/** /**
* Return the deserialized data if the signature can be verified. * Return the deserialized data if the signature can be verified.

Some files were not shown because too many files have changed in this diff Show More