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
@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
@ -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.
*/
@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.
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)
@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)
// 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) */
@KeepForDJVM
@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. " +
"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. " +
"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 txid = SecureHash.allOnesHash
private val attachmentHash = SecureHash.allOnesHash
private val factory = defaultFactory()
@Test
@ -123,4 +124,55 @@ class TransactionVerificationExceptionSerialisationTests {
assertEquals(exception.cause?.message, exception2.cause?.message)
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)
}
}