CORDA-2765 Make TransactionVerificationExceptions serializable (#4908)

This commit is contained in:
Dominic Fox 2019-03-20 17:33:37 +00:00 committed by Shams Asari
parent 52ec48d63d
commit 0ab6b4de89
2 changed files with 63 additions and 4 deletions

View File

@ -269,7 +269,7 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
*/ */
@CordaSerializable @CordaSerializable
@KeepForDJVM @KeepForDJVM
class OverlappingAttachmentsException(txId: SecureHash, 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)
/** /**
* Thrown to indicate that a contract attachment is not signed by the network-wide package owner. Please note that * Thrown to indicate that a contract attachment is not signed by the network-wide package owner. Please note that
@ -277,22 +277,29 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
* and because attachment classloaders are reused this is independent of any particular transaction. * and because attachment classloaders are reused this is independent of any particular transaction.
*/ */
@CordaSerializable @CordaSerializable
class PackageOwnershipException(txId: SecureHash, val attachmentHash: AttachmentId, val invalidClassName: String, val packageName: String) : TransactionVerificationException(txId, class PackageOwnershipException(txId: SecureHash, @Suppress("unused") val attachmentHash: AttachmentId, @Suppress("unused") val invalidClassName: String, val packageName: String) : TransactionVerificationException(txId,
"""The attachment JAR: $attachmentHash containing the class: $invalidClassName is not signed by the owner of package $packageName specified in the network parameters. """The attachment JAR: $attachmentHash containing the class: $invalidClassName is not signed by the owner of package $packageName specified in the network parameters.
Please check the source of this attachment and if it is malicious contact your zone operator to report this incident. Please check the source of this attachment and if it is malicious contact your zone operator to report this incident.
For details see: https://docs.corda.net/network-map.html#network-parameters""".trimIndent(), null) For details see: https://docs.corda.net/network-map.html#network-parameters""".trimIndent(), null)
@CordaSerializable @CordaSerializable
class InvalidAttachmentException(txId: SecureHash, attachmentHash: AttachmentId) : TransactionVerificationException(txId, class InvalidAttachmentException(txId: SecureHash, @Suppress("unused") val attachmentHash: AttachmentId) : TransactionVerificationException(txId,
"The attachment $attachmentHash is not a valid ZIP or JAR file.".trimIndent(), null) "The attachment $attachmentHash is not a valid ZIP or JAR file.".trimIndent(), null)
// 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 @KeepForDJVM
@CordaSerializable @CordaSerializable
class UntrustedAttachmentsException(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. " + "At this time these are not loadable because the DJVM sandbox has not yet been integrated. " +
"You will need to install that app version yourself, to whitelist it for use. " + "You will need to install that app version yourself, to whitelist it for use. " +
"Please follow the operational steps outlined in https://docs.corda.net/cordapp-build-systems.html#cordapp-contract-attachments to learn more and continue.") "Please follow the operational steps outlined in https://docs.corda.net/cordapp-build-systems.html#cordapp-contract-attachments to learn more and continue.")
/*
If you add a new class extending [TransactionVerificationException], please add a test in `TransactionVerificationExceptionSerializationTests`
proving that it can actually be serialised. As a rule, exceptions intended to be serialised _must_ have a corresponding readable property
for every named constructor parameter - so make your constructor parameters `val`s even if nothing other than the serializer is ever
going to read them.
*/
} }

View File

@ -24,6 +24,7 @@ class TransactionVerificationExceptionSerialisationTests {
private val context get() = AMQP_RPC_CLIENT_CONTEXT private val context get() = AMQP_RPC_CLIENT_CONTEXT
private val txid = SecureHash.allOnesHash private val txid = SecureHash.allOnesHash
private val attachmentHash = SecureHash.allOnesHash
private val factory = defaultFactory() private val factory = defaultFactory()
@Test @Test
@ -123,4 +124,55 @@ class TransactionVerificationExceptionSerialisationTests {
assertEquals(exception.cause?.message, exception2.cause?.message) assertEquals(exception.cause?.message, exception2.cause?.message)
assertEquals(exception.txId, exception2.txId) assertEquals(exception.txId, exception2.txId)
} }
@Test
fun overlappingAttachmentsExceptionTest() {
val exc = TransactionVerificationException.OverlappingAttachmentsException(txid, "foo/bar/baz")
val exc2 = DeserializationInput(factory).deserialize(
SerializationOutput(factory).serialize(exc, context),
context)
assertEquals(exc.message, exc2.message)
}
@Test
fun packageOwnershipExceptionTest() {
val exc = TransactionVerificationException.PackageOwnershipException(
txid,
attachmentHash,
"InvalidClass",
"com.invalid")
val exc2 = DeserializationInput(factory).deserialize(
SerializationOutput(factory).serialize(exc, context),
context)
assertEquals(exc.message, exc2.message)
}
@Test
fun invalidAttachmentExceptionTest() {
val exc = TransactionVerificationException.InvalidAttachmentException(
txid,
attachmentHash)
val exc2 = DeserializationInput(factory).deserialize(
SerializationOutput(factory).serialize(exc, context),
context)
assertEquals(exc.message, exc2.message)
}
@Test
fun untrustedAttachmentsExceptionTest() {
val exc = TransactionVerificationException.UntrustedAttachmentsException(
txid,
listOf(attachmentHash))
val exc2 = DeserializationInput(factory).deserialize(
SerializationOutput(factory).serialize(exc, context),
context)
assertEquals(exc.message, exc2.message)
}
} }