mirror of
https://github.com/corda/corda.git
synced 2025-04-07 11:27:01 +00:00
Merge pull request #5 from corda/composite-key-serializer
This commit is contained in:
commit
053dd9a1fe
@ -31,7 +31,13 @@ sealed class CompositeKey {
|
||||
/** Checks whether any of the given [keys] matches a leaf on the tree */
|
||||
fun containsAny(otherKeys: Iterable<PublicKey>) = keys.intersect(otherKeys).isNotEmpty()
|
||||
|
||||
// TODO: implement a proper encoding/decoding mechanism
|
||||
/**
|
||||
* This is generated by serializing the composite key with Kryo, and encoding the resulting bytes in base58.
|
||||
* A custom serialization format is being used.
|
||||
*
|
||||
* TODO: follow the crypto-conditions ASN.1 spec, some changes are needed to be compatible with the condition
|
||||
* structure, e.g. mapping a PublicKey to a condition with the specific feature (ED25519).
|
||||
*/
|
||||
fun toBase58String(): String = Base58.encode(this.serialize().bytes)
|
||||
|
||||
companion object {
|
||||
@ -124,9 +130,8 @@ sealed class CompositeKey {
|
||||
* Builds the [CompositeKey.Node]. If [threshold] is not specified, it will default to
|
||||
* the size of the children, effectively generating an "N of N" requirement.
|
||||
*/
|
||||
fun build(threshold: Int? = null): CompositeKey {
|
||||
return if (children.size == 1) children.first()
|
||||
else Node(threshold ?: children.size, children.toList(), weights.toList())
|
||||
fun build(threshold: Int? = null): CompositeKey.Node {
|
||||
return Node(threshold ?: children.size, children.toList(), weights.toList())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ import java.io.ObjectOutputStream
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.security.PublicKey
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
import javax.annotation.concurrent.ThreadSafe
|
||||
@ -302,6 +303,41 @@ object Ed25519PublicKeySerializer : Serializer<EdDSAPublicKey>() {
|
||||
}
|
||||
}
|
||||
|
||||
/** For serialising composite keys */
|
||||
@ThreadSafe
|
||||
object CompositeKeyLeafSerializer : Serializer<CompositeKey.Leaf>() {
|
||||
override fun write(kryo: Kryo, output: Output, obj: CompositeKey.Leaf) {
|
||||
val key = obj.publicKey
|
||||
kryo.writeClassAndObject(output, key)
|
||||
}
|
||||
|
||||
override fun read(kryo: Kryo, input: Input, type: Class<CompositeKey.Leaf>): CompositeKey.Leaf {
|
||||
val key = kryo.readClassAndObject(input) as PublicKey
|
||||
return CompositeKey.Leaf(key)
|
||||
}
|
||||
}
|
||||
|
||||
@ThreadSafe
|
||||
object CompositeKeyNodeSerializer : Serializer<CompositeKey.Node>() {
|
||||
override fun write(kryo: Kryo, output: Output, obj: CompositeKey.Node) {
|
||||
output.writeInt(obj.threshold)
|
||||
output.writeInt(obj.children.size)
|
||||
obj.children.forEach { kryo.writeClassAndObject(output, it) }
|
||||
output.writeInts(obj.weights.toIntArray())
|
||||
}
|
||||
|
||||
override fun read(kryo: Kryo, input: Input, type: Class<CompositeKey.Node>): CompositeKey.Node {
|
||||
val threshold = input.readInt()
|
||||
val childCount = input.readInt()
|
||||
val children = (1..childCount).map { kryo.readClassAndObject(input) as CompositeKey }
|
||||
val weights = input.readInts(childCount)
|
||||
|
||||
val builder = CompositeKey.Builder()
|
||||
weights.zip(children).forEach { builder.addKey(it.second, it.first) }
|
||||
return builder.build(threshold)
|
||||
}
|
||||
}
|
||||
|
||||
/** Marker interface for kotlin object definitions so that they are deserialized as the singleton instance. */
|
||||
interface DeserializeAsKotlinObjectDef
|
||||
|
||||
@ -344,6 +380,10 @@ fun createKryo(k: Kryo = Kryo()): Kryo {
|
||||
register(keyPair.private.javaClass, Ed25519PrivateKeySerializer)
|
||||
register(Instant::class.java, ReferencesAwareJavaSerializer)
|
||||
|
||||
// Using a custom serializer for compactness
|
||||
register(CompositeKey.Node::class.java, CompositeKeyNodeSerializer)
|
||||
register(CompositeKey.Leaf::class.java, CompositeKeyLeafSerializer)
|
||||
|
||||
// Some classes have to be handled with the ImmutableClassSerializer because they need to have their
|
||||
// constructors be invoked (typically for lazy members).
|
||||
register(SignedTransaction::class.java, ImmutableClassSerializer(SignedTransaction::class))
|
||||
|
Loading…
x
Reference in New Issue
Block a user