mirror of
https://github.com/corda/corda.git
synced 2025-02-01 08:48:09 +00:00
Simple deserialisation fixes. (#1243)
* Fix typo: prefered -> preferred * Simplify KryoVerifierSerializationScheme and resolve warning. * Add a custom serialiser for PrivacySeed so that we can avoid invoking RNG.
This commit is contained in:
parent
e453fcfdf1
commit
1672b4aa0a
@ -39,7 +39,7 @@ interface SerializationContext {
|
||||
/**
|
||||
* When serializing, use the format this header sequence represents.
|
||||
*/
|
||||
val preferedSerializationVersion: ByteSequence
|
||||
val preferredSerializationVersion: ByteSequence
|
||||
/**
|
||||
* The class loader to use for deserialization.
|
||||
*/
|
||||
|
@ -11,7 +11,7 @@ import net.corda.nodeapi.internal.serialization.amqp.SerializationOutput
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
internal val AMQP_ENABLED get() = SerializationDefaults.P2P_CONTEXT.preferedSerializationVersion == AmqpHeaderV1_0
|
||||
internal val AMQP_ENABLED get() = SerializationDefaults.P2P_CONTEXT.preferredSerializationVersion == AmqpHeaderV1_0
|
||||
|
||||
abstract class AbstractAMQPSerializationScheme : SerializationScheme {
|
||||
internal companion object {
|
||||
|
@ -6,11 +6,11 @@ import com.esotericsoftware.kryo.io.Input
|
||||
import com.esotericsoftware.kryo.io.Output
|
||||
import com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer
|
||||
import com.esotericsoftware.kryo.serializers.FieldSerializer
|
||||
import com.esotericsoftware.kryo.util.MapReferenceResolver
|
||||
import de.javakaffee.kryoserializers.ArraysAsListSerializer
|
||||
import de.javakaffee.kryoserializers.BitSetSerializer
|
||||
import de.javakaffee.kryoserializers.UnmodifiableCollectionsSerializer
|
||||
import de.javakaffee.kryoserializers.guava.*
|
||||
import net.corda.core.contracts.PrivacySalt
|
||||
import net.corda.core.crypto.composite.CompositeKey
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
@ -110,6 +110,9 @@ object DefaultKryoCustomizer {
|
||||
register(NotaryChangeWireTransaction::class.java, NotaryChangeWireTransactionSerializer)
|
||||
register(PartyAndCertificate::class.java, PartyAndCertificateSerializer)
|
||||
|
||||
// Don't deserialize PrivacySalt via its default constructor.
|
||||
register(PrivacySalt::class.java, PrivacySaltSerializer)
|
||||
|
||||
val customization = KryoSerializationCustomization(this)
|
||||
pluginRegistries.forEach { it.customizeSerialization(customization) }
|
||||
}
|
||||
@ -153,4 +156,18 @@ object DefaultKryoCustomizer {
|
||||
return list.toNonEmptySet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Avoid deserialising PrivacySalt via its default constructor
|
||||
* because the random number generator may not be available.
|
||||
*/
|
||||
private object PrivacySaltSerializer : Serializer<PrivacySalt>() {
|
||||
override fun write(kryo: Kryo, output: Output, obj: PrivacySalt) {
|
||||
output.writeBytesWithLength(obj.bytes)
|
||||
}
|
||||
|
||||
override fun read(kryo: Kryo, input: Input, type: Class<PrivacySalt>): PrivacySalt {
|
||||
return PrivacySalt(input.readBytesWithLength())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ object NotSupportedSeralizationScheme : SerializationScheme {
|
||||
override fun <T : Any> serialize(obj: T, context: SerializationContext): SerializedBytes<T> = doThrow()
|
||||
}
|
||||
|
||||
data class SerializationContextImpl(override val preferedSerializationVersion: ByteSequence,
|
||||
data class SerializationContextImpl(override val preferredSerializationVersion: ByteSequence,
|
||||
override val deserializationClassLoader: ClassLoader,
|
||||
override val whitelist: ClassWhitelist,
|
||||
override val properties: Map<Any, Any>,
|
||||
@ -52,7 +52,7 @@ data class SerializationContextImpl(override val preferedSerializationVersion: B
|
||||
})
|
||||
}
|
||||
|
||||
override fun withPreferredSerializationVersion(versionHeader: ByteSequence) = copy(preferedSerializationVersion = versionHeader)
|
||||
override fun withPreferredSerializationVersion(versionHeader: ByteSequence) = copy(preferredSerializationVersion = versionHeader)
|
||||
}
|
||||
|
||||
private const val HEADER_SIZE: Int = 8
|
||||
@ -81,7 +81,7 @@ open class SerializationFactoryImpl : SerializationFactory {
|
||||
override fun <T : Any> deserialize(byteSequence: ByteSequence, clazz: Class<T>, context: SerializationContext): T = schemeFor(byteSequence, context.useCase).deserialize(byteSequence, clazz, context)
|
||||
|
||||
override fun <T : Any> serialize(obj: T, context: SerializationContext): SerializedBytes<T> {
|
||||
return schemeFor(context.preferedSerializationVersion, context.useCase).serialize(obj, context)
|
||||
return schemeFor(context.preferredSerializationVersion, context.useCase).serialize(obj, context)
|
||||
}
|
||||
|
||||
fun registerScheme(scheme: SerializationScheme) {
|
||||
|
@ -5,6 +5,7 @@ import com.esotericsoftware.kryo.KryoSerializable
|
||||
import com.esotericsoftware.kryo.io.Input
|
||||
import com.esotericsoftware.kryo.io.Output
|
||||
import com.google.common.primitives.Ints
|
||||
import net.corda.core.contracts.PrivacySalt
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.serialization.*
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
@ -16,7 +17,9 @@ import net.corda.testing.TestDependencyInjectionBase
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.InputStream
|
||||
@ -28,6 +31,9 @@ class KryoTests : TestDependencyInjectionBase() {
|
||||
private lateinit var factory: SerializationFactory
|
||||
private lateinit var context: SerializationContext
|
||||
|
||||
@get:Rule
|
||||
val expectedEx: ExpectedException = ExpectedException.none()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
factory = SerializationFactoryImpl().apply { registerScheme(KryoServerSerializationScheme(this)) }
|
||||
@ -157,6 +163,26 @@ class KryoTests : TestDependencyInjectionBase() {
|
||||
override fun toString(): String = "Cyclic($value)"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `serialize - deserialize PrivacySalt`() {
|
||||
val expected = PrivacySalt(byteArrayOf(
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
|
||||
31, 32
|
||||
))
|
||||
val serializedBytes = expected.serialize(factory, context)
|
||||
val actual = serializedBytes.deserialize(factory, context)
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `all-zero PrivacySalt not allowed`() {
|
||||
expectedEx.expect(IllegalArgumentException::class.java)
|
||||
expectedEx.expectMessage("Privacy salt should not be all zeros.")
|
||||
PrivacySalt(ByteArray(32))
|
||||
}
|
||||
|
||||
@CordaSerializable
|
||||
private object TestSingleton
|
||||
|
||||
|
@ -111,8 +111,8 @@ class TestSerializationContext : SerializationContext {
|
||||
|
||||
override fun toString(): String = stackTrace?.joinToString("\n") ?: "null"
|
||||
|
||||
override val preferedSerializationVersion: ByteSequence
|
||||
get() = delegate!!.preferedSerializationVersion
|
||||
override val preferredSerializationVersion: ByteSequence
|
||||
get() = delegate!!.preferredSerializationVersion
|
||||
override val deserializationClassLoader: ClassLoader
|
||||
get() = delegate!!.deserializationClassLoader
|
||||
override val whitelist: ClassWhitelist
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.corda.verifier
|
||||
|
||||
import com.esotericsoftware.kryo.pool.KryoPool
|
||||
import com.typesafe.config.Config
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.typesafe.config.ConfigParseOptions
|
||||
@ -98,15 +97,10 @@ class Verifier {
|
||||
|
||||
class KryoVerifierSerializationScheme(serializationFactory: SerializationFactory) : AbstractKryoSerializationScheme(serializationFactory) {
|
||||
override fun canDeserializeVersion(byteSequence: ByteSequence, target: SerializationContext.UseCase): Boolean {
|
||||
return byteSequence.equals(KryoHeaderV0_1) && target == SerializationContext.UseCase.P2P
|
||||
return byteSequence == KryoHeaderV0_1 && target == SerializationContext.UseCase.P2P
|
||||
}
|
||||
|
||||
override fun rpcClientKryoPool(context: SerializationContext): KryoPool {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun rpcServerKryoPool(context: SerializationContext): KryoPool {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun rpcClientKryoPool(context: SerializationContext) = throw UnsupportedOperationException()
|
||||
override fun rpcServerKryoPool(context: SerializationContext) = throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user